una transformar tabla por para millas milla kilometros hora hay cuantos convertir conversiones como mapbox-gl-js

transformar - Dibujando un círculo con el radio en millas/metros con Mapbox GL JS



millas a km/h (3)

Al elaborar la respuesta de Lucas , he encontrado una forma de estimar los parámetros para dibujar un círculo basado en un determinado tamaño métrico.

El mapa admite niveles de zoom entre 0 y 20. Supongamos que definimos el radio de la siguiente manera:

"circle-radius": { stops: [ [0, 0], [20, RADIUS] ], base: 2 }

El mapa representará el círculo en todos los niveles de zoom, ya que definimos un valor para el nivel de zoom más pequeño (0) y el más grande (20). Para todos los niveles de zoom intermedios, se obtiene un radio de (aproximadamente) RADIUS/2^(20-zoom) . Por lo tanto, si configuramos RADIUS en el tamaño de píxel correcto que coincida con nuestro valor métrico, obtendremos el radio correcto para todos los niveles de zoom.

Básicamente, buscamos un factor de conversión que transforme metros en un tamaño de píxel en el nivel de zoom 20. Por supuesto, este factor depende de la latitud. Si medimos la longitud de una línea horizontal en el ecuador en el nivel máximo de zoom 20 y dividimos por el número de píxeles que abarca esta línea, obtenemos un factor de ~ 0.075 m / px (metros por píxel). Aplicando el factor de escala de latitud de mercator de 1 / cos(phi) , obtenemos la relación correcta de medidor a píxel para cualquier latitud:

const metersToPixelsAtMaxZoom = (meters, latitude) => meters / 0.075 / Math.cos(latitude * Math.PI / 180)

Por lo tanto, al establecer RADIUS en metersToPixelsAtMaxZoom(radiusInMeters, latitude) nos da un círculo con el tamaño correcto:

"circle-radius": { stops: [ [0, 0], [20, metersToPixelsAtMaxZoom(radiusInMeters, latitude)] ], base: 2 }

Estoy en el proceso de convertir un mapa de usar mapbox.js a mapbox-gl.js , y tengo problemas para dibujar un círculo que usa millas o metros para su radio en lugar de píxeles. Este círculo particular se usa para mostrar el área para la distancia en cualquier dirección desde un punto central.

Anteriormente, pude usar lo siguiente, que luego se agregó a un grupo de capas:

// 500 miles = 804672 meters L.circle(L.latLng(41.0804, -85.1392), 804672, { stroke: false, fill: true, fillOpacity: 0.6, fillColor: "#5b94c6", className: "circle_500" });

La única documentation que he encontrado para hacer esto en Mapbox GL es la siguiente:

map.addSource("source_circle_500", { "type": "geojson", "data": { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-85.1392, 41.0804] } }] } }); map.addLayer({ "id": "circle500", "type": "circle", "source": "source_circle_500", "layout": { "visibility": "none" }, "paint": { "circle-radius": 804672, "circle-color": "#5b94c6", "circle-opacity": 0.6 } });

Pero esto hace que el círculo en píxeles, que no se escala con el zoom. ¿Existe actualmente una forma con Mapbox GL de representar una capa con un círculo (o múltiple) que se basa en la distancia y las escalas con el zoom?

Actualmente estoy usando v0.19.0 de Mapbox GL.


Esta funcionalidad no está integrada en GL JS pero puede emularla usando functions .

<!DOCTYPE html> <html> <head> <meta charset=''utf-8'' /> <title></title> <meta name=''viewport'' content=''initial-scale=1,maximum-scale=1,user-scalable=no'' /> <script src=''https://api.tiles.mapbox.com/mapbox-gl-js/v0.19.0/mapbox-gl.js''></script> <link href=''https://api.tiles.mapbox.com/mapbox-gl-js/v0.19.0/mapbox-gl.css'' rel=''stylesheet'' /> <style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; } </style> </head> <body> <div id=''map''></div> <script> mapboxgl.accessToken = ''pk.eyJ1IjoibHVjYXN3b2oiLCJhIjoiNWtUX3JhdyJ9.WtCTtw6n20XV2DwwJHkGqQ''; var map = new mapboxgl.Map({ container: ''map'', style: ''mapbox://styles/mapbox/streets-v8'', center: [-74.50, 40], zoom: 9, minZoom: 5, maxZoom: 15 }); map.on(''load'', function() { map.addSource("source_circle_500", { "type": "geojson", "data": { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-74.50, 40] } }] } }); map.addLayer({ "id": "circle500", "type": "circle", "source": "source_circle_500", "paint": { "circle-radius": { stops: [ [5, 1], [15, 1024] ], base: 2 }, "circle-color": "red", "circle-opacity": 0.6 } }); }); </script> </body> </html>

Advertencias importantes:

  • Determinar los parámetros de la función para una medida particular del mundo real no es sencillo. Cambian con la longitud / latitud de la característica.
  • Los círculos de más de 1024 píxeles no se procesarán correctamente debido a la naturaleza de los datos en mosaico y la forma en que empaquetamos los datos para WebGL

Resolví este problema para mis casos de uso utilizando un polígono GeoJSON. No es estrictamente un círculo, pero al aumentar la cantidad de lados en el polígono puede acercarse bastante.

El beneficio adicional de este método es que cambiará correctamente su inclinación, tamaño, rumbo, etc. con el mapa automáticamente.

Aquí está la función para generar el Polígono GeoJSON.

var createGeoJSONCircle = function(center, radiusInKm, points) { if(!points) points = 64; var coords = { latitude: center[1], longitude: center[0] }; var km = radiusInKm; var ret = []; var distanceX = km/(111.320*Math.cos(coords.latitude*Math.PI/180)); var distanceY = km/110.574; var theta, x, y; for(var i=0; i<points; i++) { theta = (i/points)*(2*Math.PI); x = distanceX*Math.cos(theta); y = distanceY*Math.sin(theta); ret.push([coords.longitude+x, coords.latitude+y]); } ret.push(ret[0]); return { "type": "geojson", "data": { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [ret] } }] } }; };

Puedes usarlo así:

map.addSource("polygon", createGeoJSONCircle([-93.6248586, 41.58527859], 0.5)); map.addLayer({ "id": "polygon", "type": "fill", "source": "polygon", "layout": {}, "paint": { "fill-color": "blue", "fill-opacity": 0.6 } });

Si necesita actualizar el círculo que creó más tarde, puede hacerlo de esta manera (tenga en cuenta la necesidad de tomar la propiedad de data para pasar a setData):

map.getSource(''polygon'').setData(createGeoJSONCircle([-93.6248586, 41.58527859], 1).data);

Y la salida se ve así: