当前位置: 首页 > Web前端 > JavaScript

在Canvas中绘制Geojson数据

时间:2023-03-27 17:21:59 JavaScript

需求分析在做地图开发的时候遇到一个需求,就是在canvas中绘制Geojson数据。数据格式为EPSG:4326Polygon:三维数组的每一项由经纬度组成。Thefirstpointisthesameasthelastpoint.表示Polygon是闭合的[[[109.54420471485196,35.76192112844663],[109.54423617129702,35.76132766033574],[109.54539219590997,35.76155739029704],[109.54521918540507,35.76241249100947],[109.54420471485196,35.76192112844663],],];需要分析:显示在canvas的中间地图y轴与屏幕y轴相反,绘制的Polygon不能和实际的反转。屏幕原点在左上角,地图原点在左下角。数据处理宽高就是画布的宽高。将经度和纬度分开constgetLongitudesAndLatitudes=(coordinates:number[][][])=>{returncoordinates[0].reduce((pre,cur)=>{pre.longitudes.push(cur[0]);pre.latitudes.push(cur[1]);returnpre;},{longitudes:[]asnumber[],latitudes:[]asnumber[]});};结果是:constlongitudes=[109.54420471485196,109.54423617129702,109.5493929175,109.54521918540507,109.54420471485196,];const纬度=[35.76192112844663,35.76132766033574,35.76155739029704,35.76241249100947,35.76192112844663,];计算缩放比例计算Polygon的x轴缩放比例,使用width/(Math.max(longitudes)-Math.min(longitudes))xScale=67369.49567346855height同理,计算y轴的缩放比例yScale=12905.23981205731总缩放scale使用xScale和yScale,取小者,scale=12905.23981205731,因为只有小的缩放才能在有限的空间显示完整的constconstcalcScale=({longitudes,latitudes,}:{longitudes:number[];latitudes:number[];})=>{constxScale=width/Math.abs(Math.max(...longitudes)-Math.min(...longitudes));constyScale=height/Math.abs(Math.max(...latitudes)-Math.min(...latitudes));返回xScale{constxOffset=(width-Math.abs(Math.max(...longitudes)-Math.min(...longitudes))*scale)/2;constyOffset=(height-Math.abs(Math.max(...latitudes)-Math.min(...latitudes))*scale)/2;返回{xOffset,yOffset};};缩放坐标,缩放坐标分为3步,难理解的是第一步,为什么每个点都要减去它的最小值item[0]-Math.min(...longitudes)这样做的目的是使点无限接近原点,然后通过乘以Scale并加上offset来进行缩放,得到最终的缩放值。需求分析的时候说过屏幕原点在左上角,地图原点在左下角,所以y轴刚好相反,y轴使用Math.max(...latitudes)-item[1]constscaleCoordinates=(coordinates:number[][][],scale:number,offset:ReturnType,{经度,纬度}:{经度:数字[];latitudes:number[]})=>{returncoordinates[0].map((item)=>{item[0]=item[0]-Math.min(...longitudes);项目[1]=Math.max(...latitudes)-item[1];returnitem;}).map((item)=>{item[0]=item[0]*scale;item[1]=item[1]*规模;返回项目;}).map((item)=>{item[0]=item[0]+offset.xOffset;item[1]=item[1]+offset.yOffset;返回项目;});};使用画布绘制constcanvas=document.getElementById("canvas");if(!canvas.getContext)return;constctx=canvas!.getContext("2d")!;ctx.fillStyle="rgba(32,210,255,0.3)";ctx.strokeStyle="rgba(32,210,255,1)";ctx.beginPath();ctx.moveTo(坐标[0][0],坐标[0][1]);for(leti=1;i