Merge two polygons not sharing vertices.
Built with blockbuilder.org
Merge two polygons not sharing vertices.
Built with blockbuilder.org
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="//d3js.org/d3.v3.min.js"></script> | |
| <script src="//d3js.org/d3.geo.projection.v0.min.js"></script> | |
| <script src="//d3js.org/topojson.v1.min.js"></script> | |
| <style> | |
| body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
| svg { width:100%; height: 100% } | |
| .A { | |
| fill: red; | |
| stroke: yellow; | |
| stroke-width: 0.5; | |
| } | |
| .B { | |
| fill: orange; | |
| stroke: blue; | |
| stroke-width: 0.5; | |
| } | |
| .pointA { | |
| stroke: black; | |
| stroke-width: 1.5; | |
| fill: none; | |
| } | |
| .pointB { | |
| stroke: blue; | |
| stroke-width: 1.5; | |
| fill: none; | |
| } | |
| .merged { | |
| fill: green; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id='map'></div> | |
| <script> | |
| var width = 960, | |
| height = 500; | |
| var scale = Math.min(width,height) * 0.5; | |
| var svg = d3.select("#map") | |
| .append("svg") | |
| .attr("width", width) | |
| .attr("height", height); | |
| var geojObj = { | |
| "type": "FeatureCollection", | |
| "features": [ | |
| { | |
| "type": "Feature", | |
| "geometry": {"type": "Polygon", | |
| "coordinates": [ | |
| [ | |
| [ 4, 41], | |
| [ 4, 47], | |
| [ 6, 47], | |
| [ 6, 46], | |
| [ 6, 44], | |
| [ 6, 43], | |
| [ 6, 41], | |
| [ 4, 41] | |
| ] | |
| ]}, | |
| "properties": {"name": "A"} | |
| }, | |
| { | |
| "type": "Feature", | |
| "geometry": {"type": "Polygon", | |
| "coordinates": [ | |
| [ | |
| [ 7, 43], | |
| [ 6, 44], | |
| [ 6, 46], | |
| [ 7, 47], | |
| [ 7, 53], | |
| [11, 53], | |
| [11, 43], | |
| [ 7, 43] | |
| ] | |
| ]}, | |
| "properties": {"name": "B"} | |
| } | |
| ] | |
| }; | |
| // geojObj converted to topojson via http://jeffpaine.github.io/geojson-topojson/ | |
| // the following needs the lib.js from above link to work | |
| // var topojsonOutput = topojson.topology({ | |
| // collection: geojObj | |
| // }); | |
| var topoObj = { | |
| "type": "Topology", | |
| "objects": { | |
| "collection": { | |
| "type": "GeometryCollection", | |
| "geometries": [ | |
| { | |
| "type": "Polygon", | |
| "arcs": [ | |
| [ | |
| 0, | |
| 1 | |
| ] | |
| ] | |
| }, | |
| { | |
| "type": "Polygon", | |
| "arcs": [ | |
| [ | |
| -1, | |
| 2 | |
| ] | |
| ] | |
| } | |
| ] | |
| } | |
| }, | |
| "arcs": [ | |
| [ | |
| [ | |
| 2857, | |
| 4166 | |
| ], | |
| [ | |
| 0, | |
| -1666 | |
| ] | |
| ], | |
| [ | |
| [ | |
| 2857, | |
| 2500 | |
| ], | |
| [ | |
| 0, | |
| -833 | |
| ], | |
| [ | |
| 0, | |
| -1667 | |
| ], | |
| [ | |
| -2857, | |
| 0 | |
| ], | |
| [ | |
| 0, | |
| 5000 | |
| ], | |
| [ | |
| 2857, | |
| 0 | |
| ], | |
| [ | |
| 0, | |
| -834 | |
| ] | |
| ], | |
| [ | |
| [ | |
| 2857, | |
| 4166 | |
| ], | |
| [ | |
| 1428, | |
| 834 | |
| ], | |
| [ | |
| 0, | |
| 4999 | |
| ], | |
| [ | |
| 5714, | |
| 0 | |
| ], | |
| [ | |
| 0, | |
| -8332 | |
| ], | |
| [ | |
| -5714, | |
| 0 | |
| ], | |
| [ | |
| -1428, | |
| 833 | |
| ] | |
| ] | |
| ], | |
| "bbox": [ | |
| 4, | |
| 41, | |
| 11, | |
| 53 | |
| ], | |
| "transform": { | |
| "scale": [ | |
| 0.0007000700070007002, | |
| 0.0012001200120012002 | |
| ], | |
| "translate": [ | |
| 4, | |
| 41 | |
| ] | |
| } | |
| }; | |
| // find proper scale and translation from bounds of europe polygon | |
| var projection = d3.geo.azimuthalEqualArea() | |
| .scale(1) | |
| .translate([0,0]) | |
| .clipAngle(180 - 1e-3) | |
| .precision(0.1); | |
| var path = d3.geo.path().projection(projection); | |
| var b = path.bounds(geojObj), | |
| s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height), | |
| t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2]; | |
| // Update the projection to use computed scale & translate. | |
| projection | |
| .scale(s) | |
| .translate(t); | |
| var graticule = d3.geo.graticule(); | |
| svg.selectAll(".geojson").data(geojObj.features) | |
| .enter() | |
| .append("path") | |
| .attr("class",function(d){return d.properties.name;}) | |
| .attr("d", path); | |
| var pointsA = geojObj.features[0].geometry.coordinates[0], | |
| pointsB = geojObj.features[1].geometry.coordinates[0]; | |
| svg.selectAll(".pointA") | |
| .data(pointsA) | |
| .enter() | |
| .append("circle") | |
| .attr("class", "pointA") | |
| .attr("cx", function(d) { | |
| console.log(d); | |
| return projection([d[0], d[1]])[0]; | |
| }) | |
| .attr("cy", function(d) { | |
| return projection([d[0], d[1]])[1]; | |
| }) | |
| .attr("r", 5); | |
| svg.selectAll(".pointB") | |
| .data(pointsB) | |
| .enter() | |
| .append("path") | |
| .attr("transform", function(d) { | |
| return "translate(" + | |
| projection([d[0], d[1]])[0] + "," + | |
| projection([d[0], d[1]])[1] + ")"; | |
| }) | |
| .attr("d", d3.svg.symbol().type("triangle-up")); | |
| svg.append("path") | |
| .datum( | |
| topojson.merge( | |
| topoObj, | |
| topoObj.objects.collection.geometries.filter( | |
| function(d){ | |
| return true; | |
| } | |
| ))) | |
| .attr("class", "merged") | |
| .attr("transform", "translate(240, 0)") | |
| .attr("d", path); | |
| </script> | |
| </body> | |