原文链接及内容
该示例加载了TopoJSON几何图形,并使用d3 (d3.geo.path)将这些几何图形渲染为SVG元素。
TopoJSON库地址:https://github.com/topojson/topojson d3库地址:https://d3js.org/
main.js
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 import Map from 'ol/Map.js' ;import Stamen from 'ol/source/Stamen.js' ;import View from 'ol/View.js' ;import {Layer , Tile as TileLayer } from 'ol/layer.js' ;import {fromLonLat, toLonLat} from 'ol/proj.js' ;import {getCenter, getWidth} from 'ol/extent.js' ;class CanvasLayer extends Layer { constructor (options ) { super (options); this .features = options.features ; this .svg = d3 .select (document .createElement ('div' )) .append ('svg' ) .style ('position' , 'absolute' ); this .svg .append ('path' ).datum (this .features ).attr ('class' , 'boundary' ); } getSourceState ( ) { return 'ready' ; } render (frameState ) { const width = frameState.size [0 ]; const height = frameState.size [1 ]; const projection = frameState.viewState .projection ; const d3Projection = d3.geoMercator ().scale (1 ).translate ([0 , 0 ]); let d3Path = d3.geoPath ().projection (d3Projection); const pixelBounds = d3Path.bounds (this .features ); const pixelBoundsWidth = pixelBounds[1 ][0 ] - pixelBounds[0 ][0 ]; const pixelBoundsHeight = pixelBounds[1 ][1 ] - pixelBounds[0 ][1 ]; const geoBounds = d3.geoBounds (this .features ); const geoBoundsLeftBottom = fromLonLat (geoBounds[0 ], projection); const geoBoundsRightTop = fromLonLat (geoBounds[1 ], projection); let geoBoundsWidth = geoBoundsRightTop[0 ] - geoBoundsLeftBottom[0 ]; if (geoBoundsWidth < 0 ) { geoBoundsWidth += getWidth (projection.getExtent ()); } const geoBoundsHeight = geoBoundsRightTop[1 ] - geoBoundsLeftBottom[1 ]; const widthResolution = geoBoundsWidth / pixelBoundsWidth; const heightResolution = geoBoundsHeight / pixelBoundsHeight; const r = Math .max (widthResolution, heightResolution); const scale = r / frameState.viewState .resolution ; const center = toLonLat (getCenter (frameState.extent ), projection); const angle = (-frameState.viewState .rotation * 180 ) / Math .PI ; d3Projection .scale (scale) .center (center) .translate ([width / 2 , height / 2 ]) .angle (angle); d3Path = d3Path.projection (d3Projection); d3Path (this .features ); this .svg .attr ('width' , width); this .svg .attr ('height' , height); this .svg .select ('path' ).attr ('d' , d3Path); return this .svg .node (); } } const map = new Map ({ layers : [ new TileLayer ({ source : new Stamen ({ layer : 'watercolor' , }), }), ], target : 'map' , view : new View ({ center : fromLonLat ([-97 , 38 ]), zoom : 4 , }), }); d3.json ('data/topojson/us.json' ).then (function (us ) { const layer = new CanvasLayer ({ features : topojson.feature (us, us.objects .counties ), }); map.addLayer (layer); });
界面布局文件index.html
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > d3 Integration</title > <link rel ="stylesheet" href ="node_modules/ol/ol.css" > <style > .map { width : 100% ; height : 400px ; } path.boundary { fill: none; stroke: #777 ; } </style > </head > <body > <div id ="map" class ="map" > </div > <script src ="https://cdn.jsdelivr.net/npm/elm-pep@1.0.6/dist/elm-pep.js" > </script > <script src ="https://cdn.jsdelivr.net/npm/d3@7.4.4/dist/d3.min.js" > </script > <script src ="https://cdn.jsdelivr.net/npm/topojson@3.0.2/dist/topojson.js" > </script > <script type ="module" src ="main.js" > </script > </body > </html >