【问题标题】:How to add predefined places/markers to Leaflet Geocoder如何将预定义的地点/标记添加到 Leaflet Geocoder
【发布时间】:2021-01-03 16:41:40
【问题描述】:

我正在使用带有地理编码器 (ESRI) 和路由机的 Leaflet Map。 我添加了两个标记,比如说我的家和我的工作

var marker_work = L.marker([50.27, 19.03], { title: 'MyWork'}).addTo(map)
.bindPopup("work").openPopup();

var marker_home = L.marker([50.10, 18.4], { title: 'MyHome'}).addTo(map)
.bindPopup("home").openPopup();

这是一个示例小提琴: https://jsfiddle.net/21nmk8so/1/

如何将此标记/点添加为 ControlGeocoder 的预定义位置? 我想在搜索中使用它们并用作路线计算的起点/终点。

同一问题的另一个示例:如何添加带有纬度/经度的自定义假城市,并能够搜索(查找路线)往返该城市。

【问题讨论】:

  • 您只需传递用于添加标记的相同坐标,waypoints 上的标记会自动添加到第一个问题。
  • @kboul 但是如何才能通过标记名称进行搜索?
  • 您想在右侧面板上使用标记弹出文本作为开始/结束名称吗?
  • @kboul 在我的真实案例中,我有很多标记,它们是 gps 跟踪系统中的汽车。我想要做的是能够通过汽车名称(标记名称)进行搜索并导航例如从我的“汽车 A”到“柏林”,反之亦然
  • 我不知道该怎么做,但还有另一种可能的替代解决方案。您只需单击作为汽车位置的地点/标记,然后将位置设置在起点或终点。

标签: leaflet geocoder leaflet-routing-machine esri-leaflet-geocoder


【解决方案1】:

我不知道这是否是最好的解决方案,但它正在工作: 创建一个覆盖geocode 函数的自定义地理编码器类。在那里您可以覆盖结果函数并将建议应用于结果。

L.CustomGeocoder = L.Control.Geocoder.Nominatim.extend({
    suggestions: [],
    setSuggestions(arr){
      this.suggestions = arr;
    },
    createSuggestionFromMarker(marker){
      this.suggestions.push({name: marker.options.title, center: marker.getLatLng()});
    },
    getResultsOfSuggestions(query){
      var results = [];
      this.suggestions.forEach((point)=>{
        if(point.name.indexOf(query) > -1){
          point.center = L.latLng(point.center);
          point.bbox = point.center.toBounds(100);
          results.push(point);
        }
      });
      return results;
    },
    geocode(query, resultFnc, context) {
      var that = this;
      var callback = function(results){
        var sugg = that.getResultsOfSuggestions(query);
        resultFnc.call(this,sugg.concat(results));
      }
      L.Control.Geocoder.Nominatim.prototype.geocode.call(that,query, callback, context);
    }
  })

那么你必须使用新的 Geocoder 类:

var geocoder = new L.CustomGeocoder({});

var control = L.Routing.control({
  waypoints: [],
  router: new L.Routing.osrmv1({
    language: 'en',
    profile: 'car'
  }),
  geocoder: geocoder
}).addTo(map);

最后,您可以在标记和 title 选项上添加建议,而不是 createSuggestionFromMarker(marker)setSuggestions(arr)

var suggestions = [
  {
    name: 'Test Car 1',
    center: [50.27, 19.03]
  },
  {
    name: 'Test Car 2',
    center: [50.10, 18.4]
  }
];
geocoder.setSuggestions(suggestions);

var marker_work = L.marker([50.27, 19.03], { title: 'MyWork'}).addTo(map);
var marker_home = L.marker([50.10, 18.4], { title: 'MyHome'}).addTo(map);

geocoder.createSuggestionFromMarker(marker_work);
geocoder.createSuggestionFromMarker(marker_home);

更新,使用标记 Ref 而不是 fix latlng

更改这两个函数,然后引用标记,它总是从标记的当前位置开始搜索:


    createSuggestionFromMarker(marker){
      this.suggestions.push({name: marker.options.title, marker: marker});
    },
    getResultsOfSuggestions(query){
      var results = [];
      this.suggestions.forEach((point)=>{
        if(point.name.indexOf(query) > -1){
            if(point.marker){
            point.center = point.marker.getLatLng();
          }
          point.center = L.latLng(point.center);
          point.bbox = point.center.toBounds(100);
          results.push(point);
        }
      });
      return results;
    },

您可以在演示中进行测试,当您拖动标记时

https://jsfiddle.net/falkedesign/hu25jfd1/

【讨论】:

  • 感谢您的贡献。我想检查您的解决方案,但 jsfiddle 似乎没有保存。你能检查一下或更新一下吗?
  • @falkie-design 太好了,这实际上解决了我的问题,但我对一件事感到困惑。当我的汽车移动时,我可以更新标记位置,但如何更新建议(例如,让 MyWork 在建议中使用新的纬度/经度而不重复)?我的意思是像updateSuggestion这样的东西,可以这样做吗?如果您能提供帮助,我将不胜感激,但无论如何我都会将您的查询标记为已解决。谢谢
  • 我更新了答案。现在它被引用到标记并使用当前位置。如果您需要更新建议条目,您需要将其设为唯一的条目,并使用 id 或标记的_leaflet_id,然后您可以通过 id 搜索并更新对象。
  • 你好@falke-design,谢谢,这行得通。我仍在努力做的一件事是如何使搜索不区分大小写。我能够将所有建议设为小写,但如何允许搜索任何大小的标题(大写、小写、混合)jsfiddle.net/un1fc8a2/1
  • 将此行 if(point.name.indexOf(query) > -1){ 更改为 if(point.name.toLowerCase().indexOf(query.toLowerCase()) > -1){。请在它起作用时接受答案,以便解决这个问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
相关资源
最近更新 更多