Mapbox using localGeocoderOnly: true 没有它就不能工作

Mapbox using localGeocoderOnly: true doesn't work without it works

我有一个带有地理编码器的 Mapbox GL JS 应用程序。这里我有一个 localGeocoder,当我没有将选项“localGeocoderOnly”设置为 true 时,它​​可以正常工作。遗憾的是,这是一项要求,我只想使用我本地的 Geocoder。

我将 matchingFeature 的选项设置为 true 和 default。两者都使用数组输出相同的对象。

Without "localGeocoderOnly: true"

With "localGeocoderOnly: true"

我正在使用 v4.5.1 地理编码器和 mapbox v2.0.1。

我如何添加地理编码器:

    private createGeoCoder(): void {
        const geocoder = new MapboxGeocoder({
          accessToken: mapboxgl.accessToken,
          localGeocoderOnly: true,
          localGeocoder: this.localSearch,
          mapboxgl: this.map
        });
        this.map.addControl(geocoder, 'top-right');
      }

编辑以获取更多信息:

这是一个 Angular 项目,地理编码器的实现如下所示。

public createGeoCoder(): void {
    const geocoder = new MapboxGeocoder({
      accessToken: mapboxgl.accessToken,
      // localGeocoderOnly: true,
      localGeocoder: this.localSearch,
      mapboxgl: this.map
    });
    this.map.addControl(geocoder, 'top-right');
  }

  public localSearch(query): any {
    const matchingFeatures = [];
    fetch('/assets/geoData/20201027-LI-Datenerfassung_Layer_def.json')
      .then(res => res.json())
      .then((data) => {
          data.features.forEach(feature => {
              if (
                feature.properties.title
                  .toLowerCase()
                  .search(query.toLowerCase()) !== -1
              ) {
                feature['place_name'] = ' ' + feature.properties.title;
                feature['center'] = feature.geometry.coordinates;
                feature['adress'] = feature.properties.adress;
                matchingFeatures.push(feature);
              }
          });
        }
      );
    console.log(matchingFeatures);
    return matchingFeatures;
  }

我在 this sample 中添加了 localGeocoderOnly: true,,看起来很有效。

可能其他部分影响了结果。您能否提供有关实施的更多信息?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Supplement forward geocoding search results from another data source</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v2.0.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v2.0.1/mapbox-gl.css" rel="stylesheet" />
<style>
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.min.js"></script>
<link
    rel="stylesheet"
    href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.css"
    type="text/css"
/>
<!-- Promise polyfill script required to use Mapbox GL Geocoder in IE 11 -->
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>
<div id="map"></div>

<script>
    mapboxgl.accessToken = 'pk.eyJ1IjoieW9jaGkiLCJhIjoiY2tjZThvdWExMDV2dDJxcDgxZzBwbzlxYSJ9.M0yRA6SXDMRgXzXGuYnvsg';
    var map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v11',
        center: [-87.6244, 41.8756],
        zoom: 13
    });

    var customData = {
        'features': [
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Lincoln Park',
                    'description':
                        'A northside park that is home to the Lincoln Park Zoo'
                },
                'geometry': {
                    'coordinates': [-87.637596, 41.940403],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Burnham Park',
                    'description': "A lakefront park on Chicago's south side"
                },
                'geometry': {
                    'coordinates': [-87.603735, 41.829985],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Millennium Park',
                    'description':
                        'A downtown park known for its art installations and unique architecture'
                },
                'geometry': {
                    'coordinates': [-87.622554, 41.882534],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Grant Park',
                    'description':
                        "A downtown park that is the site of many of Chicago's favorite festivals and events"
                },
                'geometry': {
                    'coordinates': [-87.619185, 41.876367],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Humboldt Park',
                    'description': "A large park on Chicago's northwest side"
                },
                'geometry': {
                    'coordinates': [-87.70199, 41.905423],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Douglas Park',
                    'description':
                        "A large park near in Chicago's North Lawndale neighborhood"
                },
                'geometry': {
                    'coordinates': [-87.699329, 41.860092],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Calumet Park',
                    'description':
                        'A park on the Illinois-Indiana border featuring a historic fieldhouse'
                },
                'geometry': {
                    'coordinates': [-87.530221, 41.715515],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Jackson Park',
                    'description':
                        "A lakeside park that was the site of the 1893 World's Fair"
                },
                'geometry': {
                    'coordinates': [-87.580389, 41.783185],
                    'type': 'Point'
                }
            },
            {
                'type': 'Feature',
                'properties': {
                    'title': 'Columbus Park',
                    'description':
                        "A large park in Chicago's Austin neighborhood"
                },
                'geometry': {
                    'coordinates': [-87.769775, 41.873683],
                    'type': 'Point'
                }
            }
        ],
        'type': 'FeatureCollection'
    };

    function forwardGeocoder(query) {
        var matchingFeatures = [];
        for (var i = 0; i < customData.features.length; i++) {
            var feature = customData.features[i];
            // handle queries with different capitalization than the source data by calling toLowerCase()
            if (
                feature.properties.title
                    .toLowerCase()
                    .search(query.toLowerCase()) !== -1
            ) {
                // add a tree emoji as a prefix for custom data results
                // using carmen geojson format: https://github.com/mapbox/carmen/blob/master/carmen-geojson.md
                feature['place_name'] = ' ' + feature.properties.title;
                feature['center'] = feature.geometry.coordinates;
                feature['place_type'] = ['park'];
                matchingFeatures.push(feature);
            }
        }
        return matchingFeatures;
    }

    map.addControl(
        new MapboxGeocoder({
            accessToken: mapboxgl.accessToken,
            localGeocoder: forwardGeocoder,
            localGeocoderOnly: true,
            zoom: 14,
            placeholder: 'Enter search e.g. Lincoln Park',
            mapboxgl: mapboxgl
        })
    );

附加信息:

localGeocoder不支持Promise。即它需要你的函数 returns the result immediately.

要支持基于 Promise 的自定义地理编码器,externalGeocoder was implemented in this PR and planed to release v4.6.1。不幸的是,v4.6.1被取消了,v4.7.0还没有准备好。

如果要使用externalGeocoder,建库是最快的

准备好库后,下面的代码就可以工作了。

    map.addControl(
        new MapboxGeocoder({
            accessToken: mapboxgl.accessToken,
            localGeocoder: dummy,
            localGeocoderOnly: true,
            externalGeocoder : localSearch,
            zoom: 14,
            placeholder: 'Enter search e.g. Lincoln Park',
            mapboxgl: mapboxgl
        })
    );

    function dummy() {
        console.log('dummy');
        return [];
    }

    function localSearch(query) {
      const matchingFeatures = [];
      return fetch('data.json')
        .then(res => res.json())
        .then((data) => {
            console.log(data);
            data.features.forEach(feature => {
                if (
                  feature.properties.title
                    .toLowerCase()
                    .search(query.toLowerCase()) !== -1
                ) {
                  feature['place_name'] = ' ' + feature.properties.title;
                  feature['center'] = feature.geometry.coordinates;
                  feature['adress'] = feature.properties.adress;
                  matchingFeatures.push(feature);
                }
            });

            return Promise.resolve(matchingFeatures);
          }
        );
    }

请注意

  1. 您需要设置localGeocoderOnly。此标志用于排除 Mapbox 地理编码访问 here.
  2. 您需要设置虚拟 localGeocoder 函数,因为 this code 检查该函数是否存在。
  3. 然后 this code 调用外部地理编码器,它期望 Promise 作为 return 值。