MapBox जीएल जे एस के साथ मील / मीटर में त्रिज्या के साथ एक चक्र आकर्षित

वोट
12

मैं का उपयोग करने से एक नक्शा परिवर्तित करने की प्रक्रिया में हूँ mapbox.js को MapBox-gl.js , और एक चक्र इसके बजाय त्रिज्या पिक्सल के लिए मील या मीटर का उपयोग करता है ड्राइंग परेशानी हो रही हूँ। यह विशेष रूप से चक्र एक केंद्रीय बिंदु से किसी भी दिशा में दूरी के लिए क्षेत्र को दिखाने के लिए प्रयोग किया जाता है।

इससे पहले मैं निम्नलिखित है, जो तब एक परत समूह को जोड़ा गया है का उपयोग करने में सक्षम था:

// 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
});

केवल प्रलेखन मैं MapBox जीएल में यह करने के लिए मिल गया है निम्नलिखित है:

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
    }
});

लेकिन इस पिक्सेल में चक्र है, जो ज़ूम के साथ पैमाने पर नहीं है बना देता है। वर्तमान में MapBox जीएल के साथ एक तरह से एक चक्र (या एकाधिक) है कि दूरी और ज़ूम के साथ तराजू पर आधारित है के साथ एक परत रेंडर करने के लिए है?

मैं वर्तमान में MapBox जीएल की v0.19.0 उपयोग कर रहा हूँ।

02/06/2016 को 17:29
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


4 जवाब

वोट
2

यह कार्यक्षमता जीएल जे एस में तब्दील नहीं किया है, लेकिन आप का उपयोग कर इसे का अनुकरण कर सकते हैं कार्यों

<!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>

महत्वपूर्ण चेतावनियां:

  • एक विशेष वास्तविक दुनिया माप के लिए समारोह मापदंडों का निर्धारण सरल नहीं है। वे सुविधा के देशांतर / अक्षांश के साथ बदल जाते हैं।
  • मंडलियां 1024px गुणा से भी बड़ा ठीक से प्रस्तुत करने के लिए नहीं जा रहे हैं टाइलों डेटा की प्रकृति और जिस तरह से हम WebGL के लिए डेटा पैक करने के लिए कारण
02/06/2016 को 19:30
का स्रोत उपयोगकर्ता

वोट
16

पर विस्तार से चर्चा करते लुकास 'जवाब , मैं किसी खास मीट्रिक आकार के आधार पर एक चक्र आकर्षित करने के लिए में पैरामीटर आकलन के एक तरीके के साथ आए हैं।

मानचित्र का समर्थन करता है 0 और 20 के बीच ज़ूम स्तर चलो कहते हैं कि इस प्रकार हम त्रिज्या को परिभाषित करते हैं:

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

नक्शा सभी ज़ूम स्तर पर वृत्त प्रस्तुत करना क्योंकि हम छोटी से छोटी ज़ूम स्तर (0) और सबसे बड़ा (20) के लिए मान निर्धारित जा रहा है। में यह के बीच का (लगभग) एक त्रिज्या में परिणाम सभी ज़ूम स्तर के लिए RADIUS/2^(20-zoom)। इस प्रकार, यदि हम सेट RADIUSसही पिक्सेल आकार है कि हमारे मीट्रिक मान से मेल खाता है, हम सभी ज़ूम स्तर के लिए सही त्रिज्या मिलता है।

तो हम एक रूपांतरण कारक है कि ज़ूम स्तर 20. बेशक इस पहलू अक्षांश पर निर्भर करता है पर एक पिक्सेल आकार मीटर बदल के बाद मूल रूप से कर रहे हैं। हम अधिकतम ज़ूम स्तर 20 और पिक्सेल की संख्या है कि इस लाइन तक फैला द्वारा विभाजित में भूमध्य रेखा पर एक क्षैतिज रेखा की लंबाई को मापने है, तो हम एक कारक ~ 0.075m / पिक्सल (पिक्सेल प्रति मीटर) मिलता है। के मर्केटर अक्षांश स्केलिंग कारक को लागू करने 1 / cos(phi), हम किसी भी अक्षांश के लिए पिक्सेल अनुपात करने के लिए सही मीटर प्राप्त:

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

इस प्रकार, की स्थापना RADIUSकरने के लिए metersToPixelsAtMaxZoom(radiusInMeters, latitude)हमें सही आकार के साथ एक चक्र हो जाता है:

"circle-radius": {
  stops: [
    [0, 0],
    [20, metersToPixelsAtMaxZoom(radiusInMeters, latitude)]
  ],
  base: 2
}
13/06/2016 को 15:00
का स्रोत उपयोगकर्ता

वोट
33

मैं एक GeoJSON बहुभुज का उपयोग करके अपने प्रयोग के मामलों के लिए इस समस्या का समाधान कर दिया है। यह सख्ती से एक चक्र नहीं है, लेकिन बहुभुज पर भुजाओं की संख्या में वृद्धि से आप बहुत करीब हो सकता है।

इस विधि को जोड़ा लाभ यह है कि इसे सही ढंग से स्वचालित रूप से नक्शे के साथ अपनी पिच, आकार, असर, आदि बदल जाएगा।

यहाँ समारोह 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]
                }
            }]
        }
    };
};

आप इसे इस तरह का उपयोग कर सकते हैं:

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
    }
});

आप इसे इस तरह से कर सकते हैं आप चक्र आप बाद में बनाई गई अद्यतन करना चाहते हैं (हड़पने के लिए की जरूरत है ध्यान दें datasetData को पारित करने के लिए संपत्ति):

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

और आउटपुट इस तरह दिखता है:

उदाहरण छवि

17/08/2016 को 20:14
का स्रोत उपयोगकर्ता

वोट
0

लुकास और fphilipe जवाब पूरी तरह से काम करता है! के साथ काम कर रहे लोगों के लिए प्रतिक्रिया देशी-MapBox और ड्राइंग से अधिक मानचित्र आप खाते में इस प्रकार स्क्रीन के पिक्सेल घनत्व रखना चाहिए:

  pixelValue(latitude: number, meters: number, zoomLevel: number) {
    const mapPixels = meters / (78271.484 / 2 ** zoomLevel) / Math.cos((latitude * Math.PI) / 180);
    const screenPixel = mapPixels * Math.floor(PixelRatio.get());
    return screenPixel;
  }
17/01/2020 को 10:16
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more