参考: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
} ;