首页 > 解决方案 > 在地图中生成真正的点圈

问题描述

我正在尝试围绕特定坐标生成一圈可点击点。到目前为止,我正确生成了点,但由于地球的形状,点创建的形状不是圆形。 问题示例

我不知道如何在地图上画一个真正的圆圈,我想我需要玩投影(也许?)但我不知道怎么做。这是我当前的代码:

import 'ol/ol.css';
import {Map, View} from 'ol';
import {fromLonLat} from 'ol/proj';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import OSM from 'ol/source/OSM';
import {click} from 'ol/events/condition';
import VectorSource from 'ol/source/Vector';
import Select from 'ol/interaction/Select';
import GeoJSON from 'ol/format/GeoJSON';

import { transform } from 'ol/proj';
import 'regenerator-runtime/runtime';



var raster = new TileLayer({
  source: new OSM({
    attributions: [
      'All maps © <a href="https://outdoormaps.eu/">OpeOutdoorsMap</a>',
    ],
    url: 'https://tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=583288f0eab044aa8e826df27c403ce1'
  })
});


var countries = new VectorLayer({
  source: new VectorSource({
    url: "https://raw.githubusercontent.com/tsamaya/random-points-generator/master/resources/world_countries.geojson",
    format: new GeoJSON()
  })
});

const map = new Map({
  target: 'map',
  layers: [raster,countries],
  view: new View({
    center: fromLonLat([0,0]),
    zoom: 3,
    maxZoom: 8,
    projection: 'EPSG:3857'
  })
});

var pointsLayer = null;

var selectClick = function() {

  var selectedClick = new Select({
    condition: click
  });
  map.addInteraction(selectedClick);

  if(selectedClick !== null) {

    selectedClick.on('select',async function(event) {

      if(event.target.getFeatures().getArray().length > 0) {
        //Remove previous points layer
          if(pointsLayer != null) {
            map.removeLayer(pointsLayer);
          }


          var coord = event.mapBrowserEvent.coordinate;
          coord = transform(coord, 'EPSG:3857', 'EPSG:4326');
          var features_geojson = {
              "type":"FeatureCollection",
              "features":[]
            };

          var number_of_points = 20

          var angle_value = 360 / number_of_points;
          
          for (let angle = 0; angle < 360; angle += angle_value) {
              var x = Math.cos(angle)*4 + coord[0];
              var y = Math.sin(angle)*4 + coord[1];
              var point = {
                "type":"Feature",
                "geometry":{
                    "type":"Point",
                    "coordinates":[x,y]},
                    "properties":{}
              }
              features_geojson["features"].push(point);
          }


          //Add new points to layer
          pointsLayer = new VectorLayer({
            projection: map.displayProjection,
              source: new VectorSource({
                features: (new GeoJSON()).readFeatures(features_geojson,{featureProjection:"EPSG:3857"}),
              })
            });
          //Add layer to map
          map.addLayer(pointsLayer);

      } 


    });
  }
  
}

selectClick();


谢谢你的帮助。

标签: openlayers

解决方案


您可以使用内置的方法

在地图投影中看起来像一个圆圈

import Circle from 'ol/geom/Circle'
import {fromCircle} from 'ol/geom/Polygon'

coordinatesArray = fromCircle(new Circle(center, radius), 20).getCoordinates()[0].slice(0, -1);

球体上的测地圆

import {circular} from 'ol/geom/Polygon'

coordinatesArray = circular(toLonLat(center), radius, 20).transform('EPSG:4326', map.getView().getProjection()).getCoordinates()[0].slice(0, -1);

<html>
  <head>
    <link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" type="text/css">
    <script src="https://openlayers.org/en/latest/build/ol.js"></script>
    <style>
      html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
  <div id="map" class="map"></div>
  <script>

     var source = new ol.source.Vector();

     var map = new ol.Map({
       layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        }),
        new ol.layer.Vector({
          source: source
        })
      ],
      target: 'map',
      view: new ol.View({
        center: ol.proj.fromLonLat([110, 70]),
        zoom: 4
      })
    });

    var coordinatesArray1 = ol.geom.Polygon.fromCircle(
      new ol.geom.Circle(ol.proj.fromLonLat([100, 70]), 500000), 20
    ).getCoordinates()[0].slice(0, -1);
    source.addFeature(new ol.Feature(new ol.geom.MultiPoint(coordinatesArray1)));

    var coordinatesArray2 = ol.geom.Polygon.circular(
      [120, 70], 200000, 20
    ).transform('EPSG:4326', map.getView().getProjection()).getCoordinates()[0].slice(0, -1);
    source.addFeature(new ol.Feature(new ol.geom.MultiPoint(coordinatesArray2)));

  </script>
 </body>
</html>


推荐阅读