/**
* Created with Wikiatlas.
* User: hugolpz
* Version: 2014.09.04 */
/* Sister js ***************************************************** */
/* http://wikimapsatlas.github.io/static/js/wikimaps.atlas.js **** */
/* *************************************************************** */
/* D3JS SUGAR **************************************************** */
/* Interactive clicks helpers ************************************ */
function click(a){
var name = a.properties.name || a.id ; console.log(name);
d3.select("#interactions")
.append("div")
.html('(wiki) '+name);
}
function dblclick(a){ window.location.assign("http://en.wikipedia.org/wiki/"+a.properties.name, '_blank');}
function urlToData(name_,nodejs){
var root;
return root = nodejs? "http://localhost:8080/output/"+name_ : "../output/"+name_;
}
/* Math helpers ************************************************** */
function parallel(φ, λ0, λ1) {
if (λ0 > λ1) λ1 += 360;
var dλ = λ1 - λ0,
step = dλ / Math.ceil(dλ);
return d3.range(λ0, λ1 + 0.5 * step, step).map(function(λ) { return [normalise(λ), φ]; });
}
function normalise(x) {
return (x + 180) % 360 - 180;
}
/* Frame helpers ************************************************* */
// Get Bounding Box
var getBBoxPxViaElementAttr = function (selector){
// var bb = getBBox(selector);
var bb = d3.selectAll(selector).attr("bounds").split(",");
bb = [[bb[0],bb[1]],[bb[2],bb[3]]];
return bb;
};
// Augment Bounding Box
var bbPxToAugmentBBoxPx = function (bb,marginPx) {
// [[left, top], [right, bottom]] for svg px bb
var bbOut = [[bb[0][0]-marginPx,bb[0][1]-marginPx],[bb[1][0]+marginPx,bb[1][1]+marginPx]];
return bbOut;
};
// Get Bounding Box Rectangle path
var bbPxToXmlBBoxPath = function (bb) {
var l = bb[0][0], t = bb[0][1],
r = bb[1][0], b = bb[1][1];
var path = "M "+l+','+b+' '+r+','+b+' '+r+','+t+' '+l+','+t+' Z'; // http://jsfiddle.net/jwrmwxzt/6/
return path;
};
// Get Bounding Box Circle data
var bbPxToXmlBBoxCircleData = function (bb) {
var l = bb[0][0], t = bb[0][1], r = bb[1][0], b = bb[1][1],
cx = (r+l)/2, cy=(t+b)/2, cr = (r-l)<(b-t)? (b-t)/2: (r-l)/2;
var circleData = [ cx, cy, cr ]; // http://jsfiddle.net/jwrmwxzt/6/
return circleData;
};
// Get from initial Bounding Box, wanted margin, and condition an augmented BB's path
var bbPxToAugmentedXmlBBox = function(bb,marginPx,condition) {
if (condition) {
bb = bbPxToAugmentBBoxPx(bb,marginPx);
return bbPxToXmlBBoxPath(bb);
}
};
/* Elevations helpers ******************************************** */
var getElevationsDomain = function(elevations_json){
var elevationsKeys = Object.keys(elevations_json.objects),
elevationLength = elevationsKeys.length, // 7
elevationDomain = [];
for(var i=0; i=0) {
type = min<300&&max<2000? "plain&hills":
min>=300&&max<2000? "hills":
min>=300&&max>=2000? "hills&mounts":
"all";
}else if (min<0) { type = min>-200? "sea":"deep_sea"; }
console.log("Topographic type: "+type);
return type;
};
var selectColorRange = function (elevationDomain){
var range=[],
type = elevationType(elevationDomain);
switch(type){
case "all" : range = ['#94BF8B','#EFEBC0','#AA8753','#FFFFFF']; break;
case "plain&hills" : range = ['#94BF8B','#EFEBC0','#AA8753']; break;
case "hills" : range = [ '#EFEBC0','#AA8753']; break;
case "hills&mounts" : range = [ '#EFEBC0','#AA8753','#FFFFFF']; break;
case "sea" : range = ['#71ABD8','#D8F2FE']; break;
case "deep_sea" : range = ['#002040','#71ABD8','#D8F2FE']; break;
} console.log("Topographic D3 range: "+range);
return range;
};
var topographicColorScale = function (elevationDomain){
var colorRange = selectColorRange(elevationDomain);
var d = (elevationDomain.length)/colorRange.length;
var newDomain = []; // number of elements of domain and range must be equal. See D3 > Quantitative-Scales#linear_domain > "polylinear scale"
for (var i=0; i < colorRange.length; i++){ newDomain.push(0+i*d);}
var scale = d3.scale.linear()
.domain(newDomain)
.range(colorRange);
console.log("Topographic D3 domain:"+ newDomain);
return scale;
};
/* ****************************************************** */
/* WIKIPEDIA CSS MODULE ********************************* */
// Based and extended from: https://en.wikipedia.org/wiki/Wikipedia:WikiProject_Maps/Conventions
var wp={
stroke: {
0: "stroke:none;stroke-linejoin:round;",
no:"stroke:none;stroke-linejoin:round;",
xs:"stroke-width:0.5px;stroke-linejoin:round;",
sm:"stroke-width:1.0px;stroke-linejoin:round;",
md:"stroke-width:1.5px;stroke-linejoin:round;",
lg:"stroke-width:2.0px;stroke-linejoin:round;",
xl:"stroke-width:3.0px;stroke-linejoin:round;"
},
dash: { // http://jsfiddle.net/tgq925aL/
no: "stroke-dasharray:none;", // L1
sm: "stroke-dasharray: 4,4;", // normal dash (disputed)
md: "stroke-dasharray: 8,4;", //
xl: "stroke-dasharray: 16,4,3,4;" // international
},
label: {
all : "font-family:Helvetica Neue, Helvetica, Arial, sans-serif;",
admin:"fill:#646464;",
water:"fill:#0978AB;",
transparent:"opacity:0.3;",
start : "text-anchor:start;",
middle : "text-anchor:middle;",
end : "text-anchor:end;",
xxs: "font-size:6px;",
xs: "font-size:8px;",
sm: "font-size:10px;",
md: "font-size:12px;",
xl: "font-size:16px;font-weight:900;",
xxl: "font-size:20px;font-weight:900;"
},
poi: {
admin:"fill:#646464;",
water:"fill:#0978AB;",
xs: "font-size: 8px;",
sm: "font-size:10px;",
md: "font-size:12px;",
xl: "font-size:16px;",
xxl:"font-size:20px;"
},
location: {
no: "fill:none;",
locator: "fill:#B10000;",
frame : "fill-opacity:0.3; stroke:#B10000;",
focus : "fill:#FEFEE9;",
land : "fill:#E0E0E0;",
border: "fill: none; stroke:#646464;", // line_sm
waterline: "fill: none; stroke:#0978AB;", // line_sm
waterarea: "fill:#C6ECFF;",
temp: "fill-opacity:0.6;stroke-dasharray:4,4;dasharray:4,4;"
}};
/* STYLES ******************************************************** */
var S = { // note on naming convention : if layers exist, take exact same name, #Rivers => S.Rivers.
focus : wp.location.focus+ wp.stroke.no,
land : wp.location.land + wp.stroke.no,
Disputed: wp.stroke.md + wp.dash.sm,
L1_frames : wp.location.locator + wp.location.frame + wp.stroke.md + "pointer-events:none;",
Background: wp.location.waterarea,
Rivers: wp.location.waterline, // stroke-width => computed later
Lakes : wp.location.waterline + wp.location.waterarea + wp.stroke.sm,
Coast : wp.location.waterline+ wp.stroke.md,
L0_borders : wp.location.border + wp.stroke.md + wp.dash.xl,
L1_borders : wp.location.border + wp.stroke.sm + wp.dash.no,
Places : wp.label.all+ wp.label.admin + wp.label.middle,
Places_labels : wp.label.all+ wp.label.admin + wp.label.sm,
L0_labels : wp.label.all+ wp.label.admin + wp.label.md + wp.label.middle,
L1_labels : wp.label.all+ wp.label.admin + wp.label.sm + wp.label.middle,
Elevations : "pointer-events:none;"
};
/* Hash:patterns **************************************** */
//Pattern injection : disputed-in, disputed-out
var injectPattern = function(selector){
// location maps. Note: "hash2_4" means "hash pattern overlay, 2px colored (on), 4px not colored (off)".
var pattern_disputed_in = d3.select(selector).append("defs")
.append("pattern")
.attr({ id:"hash2_4", width:"6", height:"6", patternUnits:"userSpaceOnUse", patternTransform:"rotate(-45)"})
.append("rect")
.attr({ width:"2", height:"6", transform:"translate(0,0)", fill:"#E0E0E0" }); // (!) fill: wp.location.land
var pattern_disputed_out = d3.select(selector).append("defs")
.append("pattern")
.attr({ id:"hash4_2", width:"6", height:"6", patternUnits:"userSpaceOnUse", patternTransform:"rotate(-45)"})
.append("rect")
.attr({ width:"2", height:"6", transform:"translate(0,0)", fill:"#FEFEE9" }); // (!) fill: wp.location.focus
// To style shapes:
// .attr("fill", function(d){ return d.properties.L0 === iso_a2? "url(#hash2_4)": "url(#hash4_2)"} ;)
};
/* ****************************************************** */
/* GRID MODULE ****************************************** */
var graticule = function($D3selector,step) {
d3.geo.graticule().step([step, step]);
$D3selector.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path)
.style({'fill': 'none', 'stroke': '#0978AB', 'stroke-linejoin': 'round'})
.style({'stroke-width': 0.5 });
};
/* ****************************************************** */
/* LOCATOR MAP MODULE *********************************** */
var localisator = function (hookId, width, title, id, WEST, NORTH, EAST, SOUTH, nodejs) {
/* Init ************************************************* */
var height = width;
var lon_central = function(){
var num= EAST>WEST? -(WEST+EAST)/2 : -(WEST+EAST)/2+180;
return num;
}();
var proj = d3.geo.orthographic()
.scale(1/2*width)
.rotate([ lon_central, -(NORTH+SOUTH)/2 +10 ])
.translate([width / 2 , height / 2 ])
.clipAngle(90);
var path = d3.geo.path()
.projection(proj);
/* SVG container **************************************** */
var svg = d3.select(hookId).append("svg")
.attr("id", title+"-orthographic_globe_locator_(wikiatlas_2016)")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.drag()
.origin(function() {
var rotate = proj.rotate();
return {x: 2 * rotate[0], y: -2 * rotate[1]};
})
.on("drag", function() {
proj.rotate([d3.event.x / 2, -d3.event.y / 2, proj.rotate()[2]]);
svg.selectAll("path").attr("d", path);
}))
.on("dblclick", function() {
proj.rotate([ lon_central, -(NORTH+SOUTH)/2 +10 ]);
svg.selectAll("path").attr("d", path);
});
/* SVG background *************************************** */
// Blue circle
var earthDisk = svg.append("circle")
.attr("class", "water")
.attr("cx", width/2)
.attr("cy", height/2)
.attr("r", width/2 )
.style({'fill':'#C6ECFF'})
.style({'stroke': '656565', 'stroke-width': 1.5});
// Gradiant settings
var gradient = svg.append("svg:defs")
.append("svg:linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("y1", "0%")
.attr("fx1", "30%")
.attr("fy1", "30%")
.attr("x2", "100%")
.attr("y2", "100%")
.attr("spreadMethod", "pad");
gradient.append("svg:stop") // middle step setting
.attr("offset", "50%")
.attr("stop-color", "#FFF")
.attr("stop-opacity", 0.3);
gradient.append("svg:stop") // final step setting
.attr("offset", "100%")
.attr("stop-color", "#009")
.attr("stop-opacity", 0.3);
// Gradiant-circle
var earthOcean = svg.append('circle') // append gradient to circle
.attr('cx', width / 2)
.attr('cy', height / 2)
.attr('r', width/2 )
.attr('fill', 'url(#gradient)');
var root= urlToData("world-sp.07",nodejs); timer.now("Ready to load files");
/* GIS data injection *********************************** */
d3.json(root+"/administrative.topo.json", function(error, Stone) {
// data organized
var countries = topojson.feature(Stone, Stone.objects.admin_0),
subunits = topojson.feature(Stone, Stone.objects.admin_1),
disputed = topojson.feature(Stone, Stone.objects.disputed),
places = topojson.feature(Stone, Stone.objects.places),
neighbors = topojson.neighbors(Stone.objects.admin_1.geometries),
/**/ i = -1,
/**/ n = countries.length;
var country = svg.selectAll(".country")
.data(countries.features)
.enter().append("path")
.attr("id", function(d){ return d.properties.name.replace(/ |\.|'/g, "_");} )
.attr("name", function(d){ return d.properties.name; } )
.attr("class", "country")
.attr("style","fill:#FDFBEA")
.attr("d", path);
var focus = d3.selectAll("#"+title.replace(/ |\.|'/g, "_"))
.attr("style","fill:#B10000;");
var boundaries = svg.append("path")
//.datum( topojson.mesh(world, world.objects.countries, function(a,b) { if (a!==b){var ret = b;}return ret;}))
.datum( topojson.mesh(Stone, Stone.objects.admin_0, function(a,b) { return a!==b; }))
.attr("class", "boundary")
.attr("style","fill:none;stroke: #656565; stroke-width: 0.5;")
.attr("d", path);
var graticule = svg.append("path")
.datum(d3.geo.graticule().step([20,20]))
.attr("class", "graticule")
.attr("style","fill:none;stroke:#777;stroke-width: 0.5;stroke-opacity: 0.5")
.attr("d", path);
var coast = svg.append("path")
//.datum( topojson.mesh(world, world.objects.countries, function(a,b) { if (a==b){var ret = b;}return ret;}))
.datum( topojson.mesh(Stone, Stone.objects.admin_0, function(a,b) { return a==b; }))
.attr("class", "Coast_border")
.attr("style", "fill: none; stroke: #0978AB; stroke-linejoin: round;")
.style({'stroke-width': 0.5 })
.attr("d", path);
//* Red polygon drawing
var redwindow = function(WEST,SOUTH,EAST,NORTH,hook) {
var d = 5;
// var d= (Math.abs(NORTH-SOUTH) + Math.abs(EAST-WEST)) / 20;
var geoRect = { type: "Polygon", coordinates: [
[[WEST-d,SOUTH-d]]
.concat(parallel(NORTH+d, WEST-d, EAST+d))
.concat(parallel(SOUTH-d, WEST-d, EAST+d).reverse())
]};
var area = d3.geo.path().projection(function(geoRect){return geoRect;}).area(geoRect);
console.log(area);
if(area <250){
hook.append("path")
.datum(geoRect)
.style({'fill': '#B10000', 'fill-opacity': 0.3, 'stroke': '#B10000', 'stroke-linejoin': 'round','stroke-width': 1 })
.attr("d", path);
}
};
redwindow (WEST,SOUTH,EAST,NORTH,svg);
var label = svg.append("text")
.attr("x", width / 2)
.attr("text-anchor","middle")
.text(title)
.attr("y", height * 57/100 );
});
};
/* **************************************************************** */
/* LOCATION MAP MODULE ******************************************* */
/* **************************************************************** */
var locationMap = function(hookId, width, iso_a2, title, WEST, NORTH, EAST, SOUTH, nodejs, mapType){
mapType = mapType || { rich_background: true, base_administrative:false, base_topography:true, borders: true, labels:true };
// mapType = mapType || { rich_background: true, base_administrative:true, base_topography:false, borders: true, labels:true };
console.log("locationMap()");
/* SETTINGS ******************************************************* */
// SVG injection:
var width = width || 600,
title_ = title.replace(/ /g, "_").replace(/(_)+/g, "_"),
titleId = title.replace(/[^a-zA-Z0-9]/gi, "_").replace(/(_)+/g, "_");
var svg = d3.select(hookId).append("svg:svg")
.attr('version', '1.1')
.attr("width", width)
.attr("id", titleId)
//.attr(':xmlns:xlink','').attr('xmlns:xlink','').attr('xlink','')
// .attr(':xmlns:geo','http://www.w3.org/2000/svg')
.attr(':xmlns:inkscape','http://www.inkscape.org/namespaces/inkscape')
.attr(":xmlns:cc","http://creativecommons.org/ns#");
/* var svg = d3.select(hookId).append("svg").attr("width", width)
svg.attr(':xmlns','http://www.w3.org/2000/svg') // if not: file does not appear to have any style information
.attr(':xmlns:xlink','http://www.w3.org/1999/xlink')// if not: Namespace prefix xlink for href
// no = client: no img; crowbar: raster yes; node: raster yes ?
.attr(":xmlns:rdf","http://www.w3.org/1999/02/22-rdf-syntax-ns#")
; */
$('svg').attr('xmlns:geo', 'http://www.w3.org/2000/svg');
var geo = svg.append(':geo:g')
.attr(':xmlns:geo','http://www.w3.org/2000/svg')
.attr(':geo:id','geo')
.attr(':geo:syntax', "WSEN bounding box in decimal degrees")
.attr(':geo:west', WEST)
.attr(':geo:south', SOUTH)
.attr(':geo:east', EAST)
.attr(':geo:north', NORTH)
.attr(':geo:title', title); timer.now("Wrote XML metadata (WNES, title)");
injectPattern("svg"); //Pattern injection : disputed-in, disputed-out
console.log("pattern()"); timer.now("Add patterns");
// Runs code server or client side => raster images urls
var root= urlToData(title,nodejs); timer.now("Ready to load files");
var url1 = root+"/administrative.topo.json", // https://rugger-demast.codio.io/output/"
url2 = root+"/color.jpg.b64",
url3 = root+"/trans.png.b64",
url4 = root+"/waters.topo.json",
url5 = root+"/elevations.topo.json";
queue()
.defer(d3.json, url1) // timer.now("Load file: administrative");
.defer(d3.text, url2) // timer.now("Load file: color");
.defer(d3.text, url3) // timer.now("Load file: trans");
.defer(d3.json, url4) // timer.now("Load file: waters");
.defer(d3.json, url5) // timer.now("Load file: elevations");
.await(makeMap); timer.now("Loaded files");
/* *************************************************************** */
/* *************************************************************** */
/* *************************************************************** */
// Data (getJSON: TopoJSON)
function makeMap(error, json, file2, file3, waters, elevations){ timer.now("MakeMap() start! -----------");
/* DATA ********************************************************** */
var admin_0 = topojson.feature(json, json.objects.admin_0),
admin_1 = topojson.feature(json, json.objects.admin_1),
L1_focus = admin_1.features.filter(function(d) { return d.properties.L0_name === title; }),
disputed = topojson.feature(json, json.objects.disputed),
rivers = topojson.feature(waters, waters.objects.rivers),
lakes = topojson.feature(waters, waters.objects.lakes),
places = topojson.feature(json, json.objects.places),
coast = topojson.mesh(json, json.objects.admin_0, function(a,b) { return a===b;}),
L0_border = topojson.mesh(json, json.objects.admin_0, function(a,b) { return a!==b;}),
L1_border = topojson.mesh(json, json.objects.admin_1, function(a,b) { return a !==b && a.properties.L0 === b.properties.L0 && a.properties.L0 === iso_a2; }),
Disputed_border = topojson.mesh(json, json.objects.admin_0, function(a,b) { return a===b;});
// neighbors = topojson.neighbors(Stone.objects.admin_1.geometries); // coloring: full line
// Projection default
var projection = d3.geo.mercator()
.scale(1)
.translate([0, 0]);// .pointRadius(4)
// Projection recalculated
var focusFrameGeojson = { type: "Polygon", coordinates: [ [[WEST,SOUTH],[WEST,NORTH],[EAST,NORTH],[EAST,SOUTH],[WEST,SOUTH]] ]};
var t = getTransform(focusFrameGeojson,0,width, projection);
projection
.scale(t.scale)
.translate(t.translate);
svg.attr("height", t.height);
var path = d3.geo.path()
.projection(projection); timer.now("Define projection & transformed projection");
/* *************************************************************** */
/* META ********************************************************** */
/* *************************************************************** */ timer.now("Define minor meta (svg name)!-----------");
var administrativeMeta = function (){ svg.attr("name", title_+"_administrative_map_(2016)"); };
var topographicMeta = function (){ svg.attr("name", title_+"_topographic_map_(2016)"); };
/* *************************************************************** */
/* DEFINE LAYERS DRAWING ***************************************** */
/* *************************************************************** */ timer.now("Define drawing: -----------");
var drawBackground = function() {
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'Background',':inkscape:label':'Background'})
.attr("style", S.Background)
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", t.height);
};
var drawRelief_raster = function() {
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'Relief_raster',':inkscape:label':'Relief_raster'})
.append("image")
.attr("width", width)
.attr("height", t.height)
.attr("xlink:xlink:href", "data:image/jpeg;base64," + file2); // replace link by data URI // replace href link by data URI, d3js + client handle the missing xlink
};
/* Polygons ****************************************************** */
//Append L0 polygons
var drawL0 = function() {
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'L0',':inkscape:label':'L0'})
.selectAll(".countries")
.data(admin_0.features)
.enter().append("path")
.attr("class", "L0")
.attr("code", function(d) { return d.properties.L0; })
.attr("name", function(d) { return d.properties.name; })
.attr("style", function(d){ return d.properties.L0 === iso_a2? S.focus : S.land; } )
//.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return subunits[n].color; }) + 1 | 0); }) // coloring: fill
.attr("d", path)
.on("click", click);
};
//Append L1 polygons
var drawL1 = function(){
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'L1',':inkscape:label':'L1'})
.attr("style", S.focus)
.selectAll(".subunit")
.data(L1_focus)
.enter().append("path")
.attr("code", function(d) { return d.properties.L1; })
.attr("name", function(d) { return d.properties.name; })
// .attr("style", function(d){ return d.properties.L0 === iso_a2? S.focus : S.land; } ) // filter done in data
.attr("bounds", function(d){ var bb = path.bounds(d), o = {'left':bb[0][0],'top':bb[0][1],'right':bb[1][0],'bottom':bb[1][1]}; return JSON.stringify(o);} )
.attr("area", function(d){ return path.area(d);} )
//.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return subunits[n].color; }) + 1 | 0); }) // coloring: fill
.attr("d", path )
// .on("mouseover", )
.on("click", click);
};
var drawL1_frames = function(){ svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'L1_frames',':inkscape:label':'L1_frames'})
.attr("style", S.L1_frames)
.selectAll("path")
.data(L1_focus)
.enter().append("path")
.attr("style","opacity:0;")
.attr("name", function(d){ return "Frame for "+d.properties.name;})
.attr("d", function(d){
var bb = path.bounds(d), margin=width/100*5, condition = path.area(d)<=margin*margin;
return bbPxToAugmentedXmlBBox(bb, margin, condition);
});
};
//Append disputed polygons
var drawDisputed = function(){
if(disputed.features){
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'Disputed',':inkscape:label':'Disputed'})
.attr("style", S.Disputed+"stroke:#646464;")
.selectAll(".disputed")
.data(disputed.features)
.enter().append("path")
.attr("name", function(d) { return d.properties.name; })
.attr("fill", function(d){ return d.properties.L0 === iso_a2? "url(#hash2_4)": "url(#hash4_2)";} )
.attr("d", path )
//.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return subunits[n].color; }) + 1 | 0); }) // coloring: fill
.on("click", click);
}
};
/* ************************************************************************** */
/* Elevations *************************************************************** */
var drawElevations = function(){
var svg_elevation = svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id': 'Elevations',':inkscape:label':'Elevations'});
var drawElevations = function(json_data, name, i){
var color = colorScale(i); // console.log("current: "+ i + "/" + elevationsKeys[i]+", color: "+color);
svg_elevation.append("g")
.attr({'id': name,':inkscape:label': name})
.attr("style", "fill:"+color+";"+S.Elevations )
.selectAll(".altitude")
.data(json_data.features)
.enter().append("path")
// .attr("style", function(d){ return "fill:#88BB88;fill:opacity:0.2"; } )
//.attr("style", "fill:"+S.elevations[iteration]+";" )
.attr("d", path )
.on("click",click);
};
if(elevations.objects){
var elevationsDomain = getElevationsDomain(elevations); // console.log(elevationsDomain); // [0, 100, 200, 500, 1000, 2000, 5000]
var colorScale = topographicColorScale(elevationsDomain);
var elevationsKeys = Object.keys(elevations.objects), l=elevationsKeys.length;
for(var i=0; i3? null: S.Rivers+wp.stroke.sm; })
//.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return subunits[n].color; }) + 1 | 0); }) // coloring: fill
.attr("d", path );
}
};
//Append lakes polygons
var drawLakes = function(){
if(lakes.features){
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'Lakes',':inkscape:label':'Lakes'})
.attr("style", S.Lakes)
.selectAll(".lakes")
.data(lakes.features)
.enter().append("path")
.attr("name", function(d) { return d.properties.name; })
//.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return subunits[n].color; }) + 1 | 0); }) // coloring: fill
.attr("d", path );
}
};
/* BORDERS ******************************************************** */
// Admin1-borders filtered
var drawL1_borders = function(){ svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'L1_borders',':inkscape:label':'L1_borders'})
.append("path")
.datum(L1_border)
.attr("class", "L1_border")
.attr("style", S.L1_borders) // css
.attr("d", path);
};
// Admin0-borders filtered
var drawL0_borders = function(){ svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'L0_borders',':inkscape:label':'L0_borders'})
.append("path")
.datum(L0_border)
.attr("class", "L0_border")
.attr("style", S.L0_borders) // css
.attr("d", path);
};
// Coast-borders filtered
var drawCoasts = function(){ svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'Coast',':inkscape:label':'Coast'})
.append("path")
.datum(coast )
.attr("class", "coastline")
.attr("style", S.Coast) // css
.attr("d", path);
};
/* DOT & LABELS **************************************************** */
// Places_dots: dot placement ************************************** */
var drawPlaces_dots = function(){
if(places.features){
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'Places_dots',':inkscape:label':'Places_dots'})
.attr("style", S.Places)
.selectAll("path")
.data(places.features)
.enter().append("text")
.attr("class", "place")
.attr("name", function(d) { return d.properties.name; })
.attr("x", function(d) { return path.centroid(d)[0]; })
.attr("y", function(d) { return path.centroid(d)[1]; })
.attr("dy",".33em")
.text(function(d){ var s = d.properties.status;
return s==="Admin-0 capital"? "◉": s==="Admin-1 capital"? "●" : "⚪"; // ⬤◉⍟☉⚪⚫●⚬◯★☆☆⭐ ⭑ ⭒
})
.style(function(d){ var s = d.properties.status;
return s==="Admin-0 capital"? wp.poi.xl: s==="Admin-1 capital"? wp.poi.md : wp.poi.sm; // ⬤◉●◯★☆⍟☆⭐ ⭑ ⭒
});
}
};
/* Places labels ************************************************** */
var drawPlaces_labels = function(){
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'Places_labels',':inkscape:label':'Places_labels'})
.attr("style", S.Places_labels)
.selectAll(".place-label")
.data(places.features)
.enter().append("text")
.attr("class", "place-label")
.attr("name", function(d){ return d.properties.name; })
.attr("status", function(d){ return d.properties.status;})
.attr("style", function(d){
var s,t;
d.properties.status==="Admin-0 capital"? s=wp.label.xl:
d.properties.status==="Admin-1 capital"? s=wp.label.md: s="";
d.geometry.coordinates[0] < EAST-(EAST - WEST)/10? t= "" : t="text-anchor:end;";
return s+t;
})
.attr({"dy":".33em","x":function(d) { return d.geometry.coordinates[0] < EAST-(EAST-WEST)/10 ? 5 : -5; } }) // avoid dot overlap
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })
.text(function(d) { return d.geometry.coordinates[0] < EAST-(EAST-WEST)/10 ? d.properties.name: ""; } );
};
/* L0 labels ***************************************************** */
var drawL0_labels = function(){
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'L0_labels',':inkscape:label':'L0_labels'})
.attr("style", S.L0_labels)
.selectAll(".countries-label")
.data(admin_0.features)
.enter().append("text")
.attr("style", function(d){ return d.properties.L0 === iso_a2? "visibility:none;":""; })
.attr("name", function(d) { return d.properties.name ;})
.attr("x", function (d) { return path.centroid(d)[0]; })
.attr("y", function (d) { return path.centroid(d)[1]; })
.text(function(d) { return d.properties.name; });
};
/* L1 labels ***************************************************** */
var drawL1_labels = function(){
svg.append("g")
.attr(":inkscape:groupmode","layer")
.attr({'id':'L1_labels',':inkscape:label':'L1_labels'})
.attr("style", S.L1_labels)
.selectAll(".subunit-label")
.data(L1_focus)
.enter().append("text")
.attr("class", function(d){ return d.properties.L0 === iso_a2? "L1_label": "L1_label invisible"; } )
.attr("name", function(d) { return d.properties.name ;})
.attr("x", function (d) { return path.centroid(d)[0]; })
.attr("y", function (d) { return path.centroid(d)[1]; })
.text(function(d) { return d.properties.name; });
};
/* DRAWING ! ***************************************************** */
timer.now("Start drawing!-----------");
if(mapType.rich_background){
drawBackground(); timer.now("Background");
drawRelief_raster(); timer.now("Relief_raster");
}else{
drawBackground(); timer.now("Background");
}
if(mapType.base_administrative){
administrativeMeta();
drawL0(); timer.now("L0");
// drawElevations();
drawL1(); timer.now("L1");
}
if(mapType.base_topography){
topographicMeta();
drawL0(); d3.selectAll(hookId+' #L0 > *').attr("style","fill:#94BF8B;"); timer.now("L0");
drawElevations(); timer.now("Elevations");
drawL1(); d3.select(hookId+' #L1').attr("style","opacity:0;"); timer.now("L1");
}
if(mapType.base_topography || mapType.base_administrative ){
drawHillshade_raster(); timer.now("Hillshade_raster");
drawRivers(); timer.now("Rivers");
drawLakes(); timer.now("Lakes");
drawCoasts(); timer.now("Coasts");
}
if(mapType.borders && mapType.base_administrative){
drawDisputed(); d3.select(hookId+' #Disputed').style({"opacity":0.6}); timer.now("Disputed");
}else if(mapType.borders && mapType.base_topography){
drawDisputed(); d3.select(hookId+' #Disputed').style({"opacity":0.4}); timer.now("Disputed");}
if(mapType.borders){
drawL1_borders(); timer.now("L1_borders");
drawL0_borders(); timer.now("L0_borders");
drawL1_frames(); timer.now("L1_frames");
}
if(mapType.labels){
drawPlaces_dots(); timer.now("Places_dots");
drawPlaces_labels(); timer.now("Places_labels");
drawL0_labels(); timer.now("L0_labels");
drawL1_labels(); timer.now("L1_labels");
}
timer.toll(timer);
console.log("layers end");
}
};//END fn.InjectMap*/
/* ****************************************************** */
/* D3 helpers ****************************** */
var getTransform = function(d,padding_pc, width, projection) {
var pd = (100-(2*padding_pc))/100 || (100-(2*5))/100; // default to .9
/* GEOJSON PROFILING *********************************** */
var b = d3.geo.path()
.projection(projection)
.bounds(d); // [left, bottom], [right, top] // W S E N
// b.w = b[0][0]; b.s = b[0][1]; b.e = b[1][0]; b.n = b[1][1];
b.dx = Math.abs(b[1][0] - b[0][0]); // distance x = E-W
b.dy = Math.abs(b[1][1] - b[0][1]); // distance y = N-S
b.cx = (b[1][0] + b[0][0]) / 2; // center x
b.cy = (b[1][1] + b[0][1]) /2; // center y
//compute meaningful ratio, scale, translation
var t={};
t.ratio = ( b.dy / b.dx );
if (typeof height==="undefined"){ t.height=width*t.ratio;}
else { t.height = height; console.log("height");}
t.scale = pd * Math.min( width/b.dx, t.height/b.dy); // default: .9 * ( width / b.dx)
t.translate = [(width/2- t.scale * b.cx), (t.height/2 - t.scale * b.cy) ]; //translation
return t;
};
/* ****************************************************** */
/* DOWNLOAD BUTTONS MODULE ****************************** */
var downloadButtons = function(selector, projection){
var proj = projection || 0;
d3.select(selector).html("").append("button")
.attr("type","button")
.attr("class", "download btn btn-warning btn-md glyphicon glyphicon-download-alt")
.style({
background: "#333",
color: "#FFF",
"font-weight": 900,
border: "2px solid #B10000",
"text-decoration":"none"})
.on("click", function () {
// clip if it's a map:
if(proj !== 0 ) {
// CLIPING DESTROY THE MAP, how to save the clip dom in variable ?
var dx = svg.attr("width"); var dy = svg.attr("height");
projection.clipExtent([[0,0],[dx,dy]]); console.log(projection.scale());
svg.selectAll("path").attr("d", path);
}
// download:
console.log('2');
var e = document.createElement('script');
if (window.location.protocol === 'https:') {
e.setAttribute('src', '../js/svg-crowbar.js'); }
else { e.setAttribute('src', '../js/svg-crowbar.js'); }
e.setAttribute('class', 'svg-crowbar');
document.body.appendChild(e); })
.text(" Download"); /* -- Works on Chrome. Feedback welcome for others web browsers.*/
};
/* ****************************************************** */
/* TIMER (performance check) **************************** */
// use: var timer = []; timer.push([now(),"comment"]); timer.push([now(),"comment"]); cl.timer(timer);
var timer = {a:[]};
timer.now = function(comment) { timer.a.push([new Date(), comment|| "" ]) }
timer.toll = function(){
var array = timer.a;
for(var i=0; ix+1
} console.log("Period_0⟶"+(array.length-1)+" : "+(array[array.length-1][0]-array[0][0])/1000+"sec. (total) <-----------------------"); // total period
};
/* ****************************************************** */
/* SELECT LANGUAGE MODULE ******************************* */
// 1_wiki_translate
var wikis = {"aa":"Qafár af (Afar)","ab":"Аҧсшәа (Abkhazian)","ace":"Acèh (Achinese)","af":"Afrikaans (Afrikaans)","ak":"Akan (Akan)","als":"Alemannisch (Alemannisch)","am":"አማርኛ (Amharic)","an":"aragonés (Aragonese)","ang":"Ænglisc (Old English)","ar":"العربية (Arabic)","arc":"ܐܪܡܝܐ (Aramaic)","arz":"مصرى (Egyptian Spoken Arabic)","as":"অসমীয়া (Assamese)","ast":"asturianu (Asturian)","av":"авар (Avaric)","ay":"Aymar aru (Aymara)","az":"azərbaycanca (Azerbaijani)","ba":"башҡортса (Bashkir)","bar":"Boarisch (Bavarian)","bat-smg":"žemaitėška (Samogitian)","bcl":"Bikol Central (Bikol Central)","be":"беларуская (Belarusian)","be-x-old":"беларуская (тарашкевіца) (беларуская (тарашкевіца))","bg":"български (Bulgarian)","bh":"भोजपुरी (भोजपुरी)","bi":"Bislama (Bislama)","bjn":"Bahasa Banjar (Banjar)","bm":"bamanankan (Bambara)","bn":"বাংলা (Bengali)","bo":"བོད་ཡིག (Tibetan)","bpy":"বিষ্ণুপ্রিয়া মণিপুরী (Bishnupuriya Manipuri)","br":"brezhoneg (Breton)","bs":"bosanski (Bosnian)","bug":"ᨅᨔ ᨕᨘᨁᨗ (Buginese)","bxr":"буряад (буряад)","ca":"català (Catalan)","cbk-zam":"Chavacano de Zamboanga (Chavacano de Zamboanga)","cdo":"Mìng-dĕ̤ng-ngṳ̄ (Min Dong Chinese)","ce":"нохчийн (Chechen)","ceb":"Cebuano (Cebuano)","ch":"Chamoru (Chamorro)","cho":"Choctaw (Choctaw)","chr":"ᏣᎳᎩ (Cherokee)","chy":"Tsetsêhestâhese (Cheyenne)","ckb":"کوردی (Sorani Kurdish)","co":"corsu (Corsican)","cr":"Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ (Cree)","crh":"qırımtatarca (Crimean Turkish)","cs":"čeština (Czech)","csb":"kaszëbsczi (Kashubian)","cu":"словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ (Church Slavic)","cv":"Чӑвашла (Chuvash)","cy":"Cymraeg (Welsh)","da":"dansk (Danish)","de":"Deutsch (German)","diq":"Zazaki (Zazaki)","dsb":"dolnoserbski (Lower Sorbian)","dv":"ދިވެހިބަސް (Divehi)","dz":"ཇོང་ཁ (Dzongkha)","ee":"eʋegbe (Ewe)","el":"Ελληνικά (Greek)","eml":"emiliàn e rumagnòl (Emiliano-Romagnolo)","en":"English (English)","eo":"Esperanto (Esperanto)","es":"español (Spanish)","et":"eesti (Estonian)","eu":"euskara (Basque)","ext":"estremeñu (Extremaduran)","fa":"فارسی (Persian)","ff":"Fulfulde (Fulah)","fi":"suomi (Finnish)","fiu-vro":"Võro (Võro)","fj":"Na Vosa Vakaviti (Fijian)","fo":"føroyskt (Faroese)","fr":"français (French)","frp":"arpetan (Franco-Provençal)","frr":"Nordfriisk (Northern Frisian)","fur":"furlan (Friulian)","fy":"Frysk (Western Frisian)","ga":"Gaeilge (Irish)","gag":"Gagauz (Gagauz)","gan":"贛語 (Gan)","gd":"Gàidhlig (Scottish Gaelic)","gl":"galego (Galician)","glk":"گیلکی (Gilaki)","gn":"Avañe`ẽ (Guarani)","got":"?ミフ?ミフᄍ?ミフᄎ (Gothic)","gu":"ગુજરાતી (Gujarati)","gv":"Gaelg (Manx)","ha":"Hausa (Hausa)","hak":"客家語/Hak-kâ-ngî (Hakka)","haw":"Hawai`i (Hawaiian)","he":"עברית (Hebrew)","hi":"हिन्दी (Hindi)","hif":"Fiji Hindi (Fiji Hindi)","ho":"Hiri Motu (Hiri Motu)","hr":"hrvatski (Croatian)","hsb":"hornjoserbsce (Upper Sorbian)","ht":"Kreyòl ayisyen (Haitian)","hu":"magyar (Hungarian)","hy":"Հայերեն (Armenian)","hz":"Otsiherero (Herero)","ia":"interlingua (Interlingua)","id":"Bahasa Indonesia (Indonesian)","ie":"Interlingue (Interlingue)","ig":"Igbo (Igbo)","ii":"ꆇꉙ (Sichuan Yi)","ik":"Iñupiak (Inupiaq)","ilo":"Ilokano (Iloko)","io":"Ido (Ido)","is":"íslenska (Icelandic)","it":"italiano (Italian)","iu":"ᐃᓄᒃᑎᑐᑦ/inuktitut (Inuktitut)","ja":"日本語 (Japanese)","jbo":"Lojban (Lojban)","jv":"Basa Jawa (Javanese)","ka":"ქართული (Georgian)","kaa":"Qaraqalpaqsha (Kara-Kalpak)","kab":"Taqbaylit (Kabyle)","kbd":"Адыгэбзэ (Kabardian)","kg":"Kongo (Kongo)","ki":"Gĩkũyũ (Kikuyu)","kj":"Kwanyama (Kuanyama)","kk":"қазақша (Kazakh)","kl":"kalaallisut (Kalaallisut)","km":"ភាសាខ្មែរ (Khmer)","kn":"ಕನ್ನಡ (Kannada)","ko":"한국어 (Korean)","koi":"Перем Коми (Komi-Permyak)","kr":"Kanuri (Kanuri)","krc":"къарачай-малкъар (Karachay-Balkar)","ks":"कॉशुर / کٲشُر (Kashmiri)","ksh":"Ripoarisch (Colognian)","ku":"Kurdî (Kurdish)","kv":"коми (Komi)","kw":"kernowek (Cornish)","ky":"Кыргызча (Kyrgyz)","la":"Latina (Latin)","lad":"Ladino (Ladino)","lb":"Lëtzebuergesch (Luxembourgish)","lbe":"лакку (лакку)","lez":"лезги (Lezghian)","lg":"Luganda (Ganda)","li":"Limburgs (Limburgish)","lij":"Ligure (Ligurian)","lmo":"lumbaart (Lombard)","ln":"lingála (Lingala)","lo":"ລາວ (Lao)","lt":"lietuvių (Lithuanian)","ltg":"latgaļu (Latgalian)","lv":"latviešu (Latvian)","mai":"मैथिली (Maithili)","map-bms":"Basa Banyumasan (Basa Banyumasan)","mdf":"мокшень (Moksha)","mg":"Malagasy (Malagasy)","mh":"Ebon (Marshallese)","mhr":"олык марий (Eastern Mari)","mi":"Māori (Maori)","min":"Baso Minangkabau (Minangkabau)","mk":"македонски (Macedonian)","ml":"മലയാളം (Malayalam)","mn":"монгол (Mongolian)","mo":"молдовеняскэ (молдовеняскэ)","mr":"मराठी (Marathi)","mrj":"кырык мары (Hill Mari)","ms":"Bahasa Melayu (Malay)","mt":"Malti (Maltese)","mus":"Mvskoke (Creek)","mwl":"Mirandés (Mirandese)","my":"မြန်မာဘာသာ (Burmese)","myv":"эрзянь (Erzya)","mzn":"مازِرونی (Mazanderani)","na":"Dorerin Naoero (Nauru)","nah":"Nāhuatl (Nāhuatl)","nap":"Napulitano (Neapolitan)","nds":"Plattdüütsch (Low German)","nds-nl":"Nedersaksies (Low Saxon (Netherlands))","ne":"नेपाली (Nepali)","new":"नेपाल भाषा (Newari)","ng":"Oshiwambo (Ndonga)","nl":"Nederlands (Dutch)","nn":"norsk nynorsk (Norwegian Nynorsk)","no":"norsk bokmål (Norwegian (bokmål))","nov":"Novial (Novial)","nrm":"Nouormand (Nouormand)","nso":"Sesotho sa Leboa (Northern Sotho)","nv":"Diné bizaad (Navajo)","ny":"Chi-Chewa (Nyanja)","oc":"occitan (Occitan)","om":"Oromoo (Oromo)","or":"ଓଡ଼ିଆ (Oriya)","os":"Ирон (Ossetic)","pa":"ਪੰਜਾਬੀ (Punjabi)","pag":"Pangasinan (Pangasinan)","pam":"Kapampangan (Pampanga)","pap":"Papiamentu (Papiamento)","pcd":"Picard (Picard)","pdc":"Deitsch (Pennsylvania German)","pfl":"Pälzisch (Palatine German)","pi":"पालि (Pali)","pih":"Norfuk / Pitkern (Norfuk / Pitkern)","pl":"polski (Polish)","pms":"Piemontèis (Piedmontese)","pnb":"پنجابی (Western Punjabi)","pnt":"Ποντιακά (Pontic)","ps":"پښتو (Pashto)","pt":"português (Portuguese)","qu":"Runa Simi (Quechua)","rm":"rumantsch (Romansh)","rmy":"Romani (Romani)","rn":"Kirundi (Rundi)","ro":"română (Romanian)","roa-rup":"armãneashti (Aromanian)","roa-tara":"tarandíne (tarandíne)","ru":"русский (Russian)","rue":"русиньскый (Rusyn)","rw":"Kinyarwanda (Kinyarwanda)","sa":"संस्कृतम् (Sanskrit)","sah":"саха тыла (Sakha)","sc":"sardu (Sardinian)","scn":"sicilianu (Sicilian)","sco":"Scots (Scots)","sd":"سنڌي (Sindhi)","se":"sámegiella (Northern Sami)","sg":"Sängö (Sango)","sh":"srpskohrvatski / српскохрватски (Serbo-Croatian)","si":"සිංහල (Sinhala)","simple":"Simple English (Simple English)","sk":"slovenčina (Slovak)","sl":"slovenščina (Slovenian)","sm":"Gagana Samoa (Samoan)","sn":"chiShona (Shona)","so":"Soomaaliga (Somali)","sq":"shqip (Albanian)","sr":"српски / srpski (Serbian)","srn":"Sranantongo (Sranan Tongo)","ss":"SiSwati (Swati)","st":"Sesotho (Southern Sotho)","stq":"Seeltersk (Saterland Frisian)","su":"Basa Sunda (Sundanese)","sv":"svenska (Swedish)","sw":"Kiswahili (Swahili)","szl":"ślůnski (Silesian)","ta":"தமிழ் (Tamil)","te":"తెలుగు (Telugu)","tet":"tetun (Tetum)","tg":"тоҷикӣ (Tajik)","th":"ไทย (Thai)","ti":"ትግርኛ (Tigrinya)","tk":"Türkmençe (Turkmen)","tl":"Tagalog (Tagalog)","tn":"Setswana (Tswana)","to":"lea faka-Tonga (Tongan)","tpi":"Tok Pisin (Tok Pisin)","tr":"Türkçe (Turkish)","ts":"Xitsonga (Tsonga)","tt":"татарча/tatarça (Tatar)","tum":"chiTumbuka (Tumbuka)","tw":"Twi (Twi)","ty":"reo tahiti (Tahitian)","tyv":"тыва дыл (Tuvinian)","udm":"удмурт (Udmurt)","ug":"ئۇيغۇرچە / Uyghurche (Uyghur)","uk":"українська (Ukrainian)","ur":"اردو (Urdu)","uz":"oʻzbekcha (Uzbek)","ve":"Tshivenda (Venda)","vec":"vèneto (Venetian)","vep":"vepsän kel’ (Veps)","vi":"Tiếng Việt (Vietnamese)","vls":"West-Vlams (West Flemish)","vo":"Volapük (Volapük)","wa":"walon (Walloon)","war":"Winaray (Waray)","wo":"Wolof (Wolof)","wuu":"吴语 (Wu)","xal":"хальмг (Kalmyk)","xh":"isiXhosa (Xhosa)","xmf":"მარგალური (Mingrelian)","yi":"ייִדיש (Yiddish)","yo":"Yorùbá (Yoruba)","za":"Vahcuengh (Zhuang)","zea":"Zeêuws (Zeeuws)","zh":"中文 (Chinese)","zh-classical":"文言 (Classical Chinese)","zh-min-nan":"Bân-lâm-gú (Chinese (Min Nan))","zh-yue":"粵語 (Cantonese)","zu":"isiZulu (Zulu)"};
//Source: https://meta.wikimedia.org/wiki/Special:SiteMatrix
//Languages: 288!
/* ****************************************************** */
/* SELECT ITEM MODULE *********************************** */
// in _location
/* ****************************************************** */
/* REPROJECTION TOOLS MODULE **************************** */