@mapbox/mapbox-gl-geocoder 簡單使用

參考:https://github.com/mapbox/mapbox-gl-geocoder

https://github.com/mapbox/carmen/blob/master/carmen-geojson.md

接下來需要安裝此工具:https://github.com/mapbox/carmen

 

使用nodejs環境,用webpack打包

1.項目結構:

 

2.package.json

{
  "name": "demo001",
  "version": "1.0.0",
  "description": "20200623",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack-cli",
    "start": "webpack",
    "dev": "webpack && webpack-dev-server --open"
  },
  "keywords": [],
  "author": "aganliang",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
    "@elastic/elasticsearch": "^7.8.0",
    "@mapbox/mapbox-gl-draw": "^1.1.2",
    "@mapbox/mapbox-gl-geocoder": "^4.5.1",
    "@mapbox/mapbox-gl-language": "^0.10.1",
    "css-loader": "^3.6.0",
    "elasticsearch": "^16.7.1",
    "extract-text-webpack-plugin": "^3.0.2",
    "html-webpack-plugin": "^4.3.0",
    "mapbox-gl": "^1.11.0",
    "mapbox-gl-controls": "^1.6.4",
    "mapbox-gl-geocoder": "^2.0.1",
    "mapbox-gl-style-switcher": "^1.0.6",
    "style-loader": "^1.2.1"
  }
}

3.html模板

<!DOCTYPE html>
<html>
<head lang="en"> 
    <meta charset="UTF-8">
    <title>my mapbox</title>
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
	<style>
		body { margin: 0; padding: 0; }
		#map { position: absolute; top: 0; bottom: 0; width: 100%; }
	</style>
</head>
<body>
	<div id="map"></div>	
</body>
</html>

4.index.js

import mapboxgl from 'mapbox-gl';
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder'; 
import { esGeocoder } from './myGeocoder.js';
import { RulerControl,
		StylesControl,
		CompassControl,
		ZoomControl,
		InspectControl,
		TooltipControl,
		MapboxLanguage,
		MapboxStyleSwitcherControl,
} from './controls.js';
import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
import 'mapbox-gl/src/css/mapbox-gl.css'; 
import "mapbox-gl-style-switcher/styles.css"; 
import 'mapbox-gl-controls/theme.css';
 
mapboxgl.accessToken = 'pk.eyJ1IjoiYWdhbmxpYW5nIiwiYSI6ImNrYndkZ2dqdzBldzQycmxna3RrZ3ZrMDIifQ.mQKqeJPDcqpV7HEFSLA';
const map = new mapboxgl.Map({
	container: 'map',
	style: 'mapbox://styles/mapbox/streets-v11', 
	center: [113.254, 23.5478], // starting position [lng, lat]
	zoom: 10, 
	hash:true,
});
 
// 添加相關的地圖控件
// map.addControl(new mapboxgl.NavigationControl()); 
const scale = new mapboxgl.ScaleControl({
    maxWidth: 80,
    unit: 'imperial'
});
map.addControl(scale);
scale.setUnit('metric');  
map.addControl(new MapboxStyleSwitcherControl()); 
map.addControl(new CompassControl(), 'top-right'); 
map.addControl(new ZoomControl(), 'top-right'); 
map.addControl(new mapboxgl.FullscreenControl()); 
map.addControl(new MapboxLanguage({
  defaultLanguage: 'zh'
})); 
// map.addControl(new InspectControl(), 'bottom-right'); 
// map.addControl(new TooltipControl({ layer: '$fill' })); 
map.addControl(new RulerControl(), 'top-right');
map.on('ruler.on', () => console.log('ruler: on'));
map.on('ruler.off', () => console.log('ruler: off')); 

// geocoder
const geocoder = new MapboxGeocoder(
	{ 
		accessToken: mapboxgl.accessToken ,
		minLength:2,
		limit:12,
		types:'poi',
		//localGeocoderOnly:true,
		localGeocoder: esGeocoder,
		placeholder:'請輸入關鍵字',
		mapboxgl: mapboxgl
	}
);
//geocoder.addTo('#geocoder');
map.addControl(geocoder,'top-left');


// 添加maker
const marker = new mapboxgl.Marker()
.setLngLat([113.369, 23.456])
.addTo(map);

5.myGeocoder.js

const es = require('elasticsearch');
const client = new es.Client({
    host: '192.168.1.7:9200',
    log: 'error'
});

const search = function search(index, body) {
    return client.search({
      index: index, body: body
    });
};

const index = ['gis']

export function esGeocoder(query) {
  var matchingFeatures = [];
  let body = {
      from: 0,
      size: 12,
      query: {
        match: { name: {query} }
    }
  };
  // match anything which looks like a decimal degrees coordinate pair
  var matches = query.match(
     /^[ ]*(?:Lat: )?(-?\d+\.?\d*)[, ]+(?:Lng: )?(-?\d+\.?\d*)[ ]*$/i
  );
  // 如果不匹配經緯度查詢,那麼就查詢es
  if (!matches) {
    search(index[0], body)
        .then(results => {      
            for (var i = 0; i < results.hits.hits.length; i++) {
              var feature = results.hits.hits[i];
              // 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
              //console.log(feature._source);
              feature['text'] = feature._source.name;
              feature['place_name'] = '🏠 ' + feature._source.name +','+ feature._source.address ;
              feature['center'] = [feature._source.location.lon, feature._source.location.lat] ;
              feature['place_type'] = ['poi'];
              matchingFeatures.push(feature);
            }
        })
        .catch(console.error);
    return matchingFeatures;
  }
  // 如果匹配經緯度查詢的正則表達式
/* given a query in the form "lng, lat" or "lat, lng" returns the matching
* geographic coordinate(s) as search results in carmen geojson format,
* https://github.com/mapbox/carmen/blob/master/carmen-geojson.md
*/
  function coordinateFeature(lng, lat) {
      return {
        center: [lng, lat],
        geometry: {
          type: 'Point',
          coordinates: [lng, lat]
        },
        place_name: '緯度: ' + lat + ' 經度: ' + lng,
        place_type: ['coordinate'],
        properties: {},
        type: 'Feature'
        };
      }
       
      var coord1 = Number(matches[1]);
      var coord2 = Number(matches[2]);
      var geocodes = [];
       
      if (coord1 < -90 || coord1 > 90) {
        // must be lng, lat
        geocodes.push(coordinateFeature(coord1, coord2));
      }
         
      if (coord2 < -90 || coord2 > 90) {
        // must be lat, lng
        geocodes.push(coordinateFeature(coord2, coord1));
      }
         
      if (geocodes.length === 0) {
        // else could be either lng, lat or lat, lng
        geocodes.push(coordinateFeature(coord1, coord2));
        geocodes.push(coordinateFeature(coord2, coord1));
      }     
      return geocodes;
};


6.controls.js

import RulerControl from 'mapbox-gl-controls/lib/ruler';
import StylesControl from 'mapbox-gl-controls/lib/styles';
import CompassControl from 'mapbox-gl-controls/lib/compass';
import ZoomControl from 'mapbox-gl-controls/lib/zoom';
//import LanguageControl from 'mapbox-gl-controls/lib/language';
import InspectControl from 'mapbox-gl-controls/lib/inspect';
import TooltipControl from 'mapbox-gl-controls/lib/tooltip'; 
import MapboxLanguage from '@mapbox/mapbox-gl-language';
import { MapboxStyleSwitcherControl } from "mapbox-gl-style-switcher";


export { 
	RulerControl,
	StylesControl,
	CompassControl,
	ZoomControl,
	InspectControl,
	TooltipControl,
	MapboxLanguage,
	MapboxStyleSwitcherControl 
} ;

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章