Когда я рисую Бермудский треугольник в элементе SVG, масштаб не такой, как я ожидал (треугольник должен простираться до краев блока), а заливка обратная (вместо рисования треугольника он рисует квадрат с вырезанным треугольником).
var geojson = {
"features": [
{
"type": "Feature",
"properties": {
"name": "Bermuda Triangle",
"area": 1150180
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-64.73, 32.31],
[-80.19, 25.76],
[-66.09, 18.43],
[-64.73, 32.31]
]
]
}
}
],
"type":"FeatureCollection"
};
var width = 480;
var height = 480;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("style", "border: 2px solid black");
var projection = d3.geoMercator().fitSize([width, height], geojson);
var path = d3.geoPath().projection(projection);
svg.selectAll('path')
.data(geojson.features)
.enter()
.append('path')
.attr('d', path)
.style("fill", "red")
.style("stroke-width", "1")
.style("stroke", "black");
<script src="//d3js.org/d3.v4.js"></script>
Что я делаю не так?
Ответ 1 · рейтинг 11 · Gerardo Furtado
Давайте изменим это:
[
[-64.73, 32.31],
[-80.19, 25.76],
[-66.09, 18.43],
[-64.73, 32.31]
]
К этому:
[
[-64.73, 32.31],
[-66.09, 18.43],
[-80.19, 25.76],
[-64.73, 32.31]
]
Это кажется небольшим изменением, но оно очень важно: D3 ожидает, что вершины полигона расположены в порядке по часовой стрелке.
Согласно API:
Сферические многоугольники также требуют соглашения о порядке намотки, чтобы определить, какая сторона многоугольника является внутренней: внешнее кольцо для многоугольников меньше полусферы должно быть по часовой стрелке, а внешнее кольцо для многоугольников больше полусферы должно быть против часовой стрелки. (выделено мной)
Кроме того, это интересные блоки, сделанные Бостоком (создателем D3), дидактически объясняющие вашу проблему: https://bl.ocks.org/mbostock/a7bdfeb041e850799a8d3dce4d8c50c8
Вот ваш код с этим изменением (и удалением fitSize):
var geojson = {
"features": [{
"type": "Feature",
"properties": {
"name": "Bermuda Triangle",
"area": 1150180
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-64.73, 32.31],
[-66.09, 18.43],
[-80.19, 25.76],
[-64.73, 32.31]
]
]
}
}],
"type": "FeatureCollection"
};
var width = 480;
var height = 480;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("style", "border: 2px solid black");
var projection = d3.geoMercator();
var path = d3.geoPath().projection(projection);
svg.selectAll('path')
.data(geojson.features)
.enter()
.append('path')
.attr('d', path)
.style("fill", "red")
.style("stroke-width", "1")
.style("stroke", "black");
<script src="//d3js.org/d3.v4.js"></script>
Ответ 2 · рейтинг 3 · bumbeishvili
Если кто-то увидит подобную проблему, я создал инструмент, который поможет вам перемотать или реверсировать geojson
Это помогло мне внести изменения в некоторые файлы geoJson без особых хлопот.
https://observablehq.com/@bumbeishvili/rewind-geojson
Вы можете запустить его как фрагмент ниже
<div class="notebook-content">
</div>
<script type="module">
import notebook from "https://api.observablehq.com/@bumbeishvili/rewind-geojson.js"; // "download code" url
document.querySelector('.notebook-content').innerHTML =notebook.modules[0].variables
.filter(d=>d)
.map((d,i)=>` <div class=" observable-wrapper div-number-${i}"></div>`)
.join('')
.concat('<div style="display:none" class="hidden"></div>')
import {Inspector, Runtime} from "https://unpkg.com/@observablehq/runtime@3/dist/runtime.js";
let i=1;
Runtime.load(notebook, (variable) => {
if(i==4 ){i++; return new Inspector(document.querySelector(`.hidden`));}
if(i==13)return;
return new Inspector(document.querySelector(`.observable-wrapper:nth-child(${i++})`));
});
</script>