使用 mapshaper 简化 GeoJson FeatureCollection 会导致问题
Simplifying a GeoJson FeatureCollection using mapshaper causes issues
更具体地说,它会导致相同的代码在地图上呈现轮廓,并且在使用指针事件时仅识别最后一个路径元素。
我使用他们的网站在 mapshaper 上简化了一个 continents.json 文件,并替换了我的 public/data 文件夹中的文件。目前我正在获取一个组件中的数据并将其传递给另一个组件。
const WorldMapAtlas = () => {
const [continents, continents] = useState<null | FeatureCollection>(null)
useEffect(() => {
fetch('data/continents_simple.json')
.then(response => response.json())
.then((worldData) => {
let continents: FeatureCollection = (worldData as FeatureCollection)
setContinents(continents)
})
.catch(error => console.log(error))
}, [])
return (
<>
{continents &&
<div className="w-3/4" >
<TestMap projectionType={geoNaturalEarth1} GeoJson={continents} size={[928, 454]} translate={[464, 227]} />
</div>
}
</>
)
}
然后我尝试使用 TestMap 组件渲染它
interface props {
projectionType: () => GeoProjection;
GeoJson: FeatureCollection | null;
size: [number, number];
translate: [number, number];
}
const TestMap = (props: props) => {
const svgRef = useRef(null)
const [height, width] = props.size;
useEffect(() => {
//accesses the reference element
const svg = d3.select(svgRef.current)
//declares the geoJson, projection, and path(pathGenerator)
const geoJson = props.GeoJson
const projection = props.projectionType()
.fitSize(props.size, geoGraticule10())
.translate(props.translate)
const path = d3.geoPath().projection(projection)
//uses d3 to inject the data into the svg element
const features = svg.selectAll(".country")
.data(geoJson ? geoJson.features : [])
.enter().append("path")
//basic styling attributes
.attr("d", path)
.attr("fill", "none")
.attr("stroke", "aliceblue")
.attr("stroke-width", "0.5px")
//allows pointer events anywhere inside the path even when fill=none
.attr("pointer-events", "visibleFill")
.attr("visibility", "visible")
//sets the path element id to the continent name
.attr("id", (d) => {
return `${d.properties.continent}`
})
//selects the current continent and highlights it by increasing the stroke width
.on("mouseover", (d,i) => {
svg.select(`#${i.properties.continent}`).attr("stroke-width", "2px")
})
//deselects
.on("mouseleave", (d,i) => {
svg.select(`#${i.properties.continent}`).attr("stroke-width", "0.5px")
})
//adds the .country attribute to allow for later updates on the svg element
.attr("class", "country")
}, [geoJson]);
return (
<div className="bg-blue-400">
<svg ref={svgRef} viewBox={`0 0 ${props.size[0]} ${props.size[1]}`} />
</div>
)
}
export default TestMap
当我使用未简化的 json 文件时,它工作正常。每个国家都被突出显示,但笔划宽度重绘需要一段时间。当我所做的只是将 WorldMapAtlas 中的获取更改为简化的 json 时,会出现一个轮廓(它似乎并不特定于一条路径,只有在删除所有路径元素(开发工具)时才会消失),并且仅无论光标在何处,json 中的最后一个功能都会突出显示。
红点是我光标所在的位置。
我在这上面花了很多时间,非常感谢能得到的任何帮助!谢谢
在尝试了很多不同的简化选项后,我觉得自己很傻。您所要做的就是在输出命令中添加 gj2008 选项。
gj2008 [GeoJSON] use original GeoJSON spec (not RFC 7946)
这解决了所有问题!虽然我不知道为什么,但我不确定如何检查原始 GeoJSON 规范,也不确定有什么区别。希望这可以帮助 运行 遇到同样问题的任何人!
更具体地说,它会导致相同的代码在地图上呈现轮廓,并且在使用指针事件时仅识别最后一个路径元素。 我使用他们的网站在 mapshaper 上简化了一个 continents.json 文件,并替换了我的 public/data 文件夹中的文件。目前我正在获取一个组件中的数据并将其传递给另一个组件。
const WorldMapAtlas = () => {
const [continents, continents] = useState<null | FeatureCollection>(null)
useEffect(() => {
fetch('data/continents_simple.json')
.then(response => response.json())
.then((worldData) => {
let continents: FeatureCollection = (worldData as FeatureCollection)
setContinents(continents)
})
.catch(error => console.log(error))
}, [])
return (
<>
{continents &&
<div className="w-3/4" >
<TestMap projectionType={geoNaturalEarth1} GeoJson={continents} size={[928, 454]} translate={[464, 227]} />
</div>
}
</>
)
}
然后我尝试使用 TestMap 组件渲染它
interface props {
projectionType: () => GeoProjection;
GeoJson: FeatureCollection | null;
size: [number, number];
translate: [number, number];
}
const TestMap = (props: props) => {
const svgRef = useRef(null)
const [height, width] = props.size;
useEffect(() => {
//accesses the reference element
const svg = d3.select(svgRef.current)
//declares the geoJson, projection, and path(pathGenerator)
const geoJson = props.GeoJson
const projection = props.projectionType()
.fitSize(props.size, geoGraticule10())
.translate(props.translate)
const path = d3.geoPath().projection(projection)
//uses d3 to inject the data into the svg element
const features = svg.selectAll(".country")
.data(geoJson ? geoJson.features : [])
.enter().append("path")
//basic styling attributes
.attr("d", path)
.attr("fill", "none")
.attr("stroke", "aliceblue")
.attr("stroke-width", "0.5px")
//allows pointer events anywhere inside the path even when fill=none
.attr("pointer-events", "visibleFill")
.attr("visibility", "visible")
//sets the path element id to the continent name
.attr("id", (d) => {
return `${d.properties.continent}`
})
//selects the current continent and highlights it by increasing the stroke width
.on("mouseover", (d,i) => {
svg.select(`#${i.properties.continent}`).attr("stroke-width", "2px")
})
//deselects
.on("mouseleave", (d,i) => {
svg.select(`#${i.properties.continent}`).attr("stroke-width", "0.5px")
})
//adds the .country attribute to allow for later updates on the svg element
.attr("class", "country")
}, [geoJson]);
return (
<div className="bg-blue-400">
<svg ref={svgRef} viewBox={`0 0 ${props.size[0]} ${props.size[1]}`} />
</div>
)
}
export default TestMap
当我使用未简化的 json 文件时,它工作正常。每个国家都被突出显示,但笔划宽度重绘需要一段时间。当我所做的只是将 WorldMapAtlas 中的获取更改为简化的 json 时,会出现一个轮廓(它似乎并不特定于一条路径,只有在删除所有路径元素(开发工具)时才会消失),并且仅无论光标在何处,json 中的最后一个功能都会突出显示。
红点是我光标所在的位置。
我在这上面花了很多时间,非常感谢能得到的任何帮助!谢谢
在尝试了很多不同的简化选项后,我觉得自己很傻。您所要做的就是在输出命令中添加 gj2008 选项。
gj2008 [GeoJSON] use original GeoJSON spec (not RFC 7946)
这解决了所有问题!虽然我不知道为什么,但我不确定如何检查原始 GeoJSON 规范,也不确定有什么区别。希望这可以帮助 运行 遇到同样问题的任何人!