我有一个来自openlayers库的代码,以及一个用于测量地图上的长度和面积的示例。我也有一个来自Nominatim库的代码,用于在地图上进行“搜索Nominatim控件”和地理编码。我将这些代码放在一起。每个代码都可以正常工作,但不能同时使用。该错误是在这里,单击两次后不再选择要测量长度或面积的点,请告知要纠正或更改的部分。 有没有更简单的方法可以做到这一点? 谢谢
第一个用于地理编码的代码:
<!DOCTYPE html>
<html>
<head>
<!----------------------------------------------------------
Copyright (c) 2017-2018 Jean-Marc VIGLINO,
released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
------------------------------------------------------------>
<title>ol-ext: Search Nominatim control</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="Control to add a grid reference to a map." />
<meta name="keywords" content="ol3, control, search, BAN, french, places, autocomplete" />
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- IE 9 bug on ajax tranport -->
<!--[if lte IE 9]>
<script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js'></script>
<![endif]-->
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->
<link rel="stylesheet" href="http://viglino.github.io/ol-ext/dist/ol-ext.css" />
<script type="text/javascript" src="http://viglino.github.io/ol-ext/dist/ol-ext.js"></script>
<link rel="stylesheet" href="../style.css"/>
<style>
.ol-search ul {
color: #333;
font-size:0.85em;
max-width: 21em;
}
.ol-search ul i {
display: block;
color: #333;
font-size:0.85em;
}
.info {
display: inline-block;
width: 100%;
}
.info a img {
height: 100px;
margin-right: .5em;
float: left;
}
</style>
</head>
<body >
<!-- DIV pour la carte -->
<div id="map" style="width:50%; height:50%;"></div>
<div class="options">
<label>
<input id="polygon" type="checkbox" onclick="search.set('polygon', $(this).prop('checked')); search.search();" />
extract polygons<br/>(may slow down requests)
</label>
<br/>
<i>Use the search control to start a new search.</i>
</div>
<script type="text/javascript">
// Layers
var layers = [ new ol.layer.Tile({ source: new ol.source.OSM() }) ];
// The map
var map = new ol.Map
({ target: 'map',
view: new ol.View
({ zoom: 5,
center: ol.proj.fromLonLat([51.39, 35.70])
}),
interactions: ol.interaction.defaults({ altShiftDragRotate:false, pinchRotate:false }),
layers: layers
});
// Current selection
var sLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
stroke: new ol.style.Stroke ({
color: 'rgb(255,165,0)',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(255,165,0,.3)'
})
}),
stroke: new ol.style.Stroke ({
color: 'rgb(255,165,0)',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(255,165,0,.3)'
})
})
});
map.addLayer(sLayer);
// Set the search control
var search = new ol.control.SearchNominatim (
{ //target: $(".options").get(0),
polygon: $("#polygon").prop("checked"),
position: true // Search, with priority to geo position
});
map.addControl (search);
// Select feature when click on the reference index
search.on('select', function(e)
{ // console.log(e);
sLayer.getSource().clear();
// Check if we get a geojson to describe the search
if (e.search.geojson) {
var format = new ol.format.GeoJSON();
var f = format.readFeature(e.search.geojson, { dataProjection: "EPSG:4326", featureProjection: map.getView().getProjection() });
sLayer.getSource().addFeature(f);
var view = map.getView();
var resolution = view.getResolutionForExtent(f.getGeometry().getExtent(), map.getSize());
var zoom = view.getZoomForResolution(resolution);
var center = ol.extent.getCenter(f.getGeometry().getExtent());
// redraw before zoom
setTimeout(function(){
view.animate({
center: center,
zoom: Math.min (zoom, 16)
});
}, 100);
}
else {
map.getView().animate({
center:e.coordinate,
zoom: Math.max (map.getView().getZoom(),16)
});
}
});
</script>
</body>
</html>
度量区域的第二个代码:
请参见openlayers示例“度量”
两个代码都:
<!DOCTYPE html>
<html>
<head>
<title>Measure</title>
<link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v4.6.5/build/ol.js"></script>
<!---------------------------------------
-----------------------------------------
-----------------------------------------
-->
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- jQuery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<!-- IE 9 bug on ajax tranport -->
<!--[if lte IE 9]>
<script type='text/javascript' src='//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js'></script>
<![endif]-->
<!-- Openlayers -->
<link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
<!-- ol-ext -->
<link rel="stylesheet" href="http://viglino.github.io/ol-ext/dist/ol-ext.css" />
<script type="text/javascript" src="http://viglino.github.io/ol-ext/dist/ol-ext.js"></script>
<!-- <link rel="stylesheet" href="../style.css"/> -->
<style>
.ol-search ul {
color: #333;
font-size:0.85em;
max-width: 21em;
}
.ol-search ul i {
display: block;
color: #333;
font-size:0.85em;
}
.info {
display: inline-block;
width: 100%;
}
.info a img {
height: 100px;
margin-right: .5em;
float: left;
}
</style>
<!------------------------------
--------------------------------
-------------------------------->
<style>
.tooltip {
position: relative;
background: rgba(0, 0, 0, 0.5);
border-radius: 4px;
color: white;
padding: 4px 8px;
opacity: 0.7;
white-space: nowrap;
}
.tooltip-measure {
opacity: 1;
font-weight: bold;
}
.tooltip-static {
background-color: #ffcc33;
color: black;
border: 1px solid white;
}
.tooltip-measure:before,
.tooltip-static:before {
border-top: 6px solid rgba(0, 0, 0, 0.5);
border-right: 6px solid transparent;
border-left: 6px solid transparent;
content: "";
position: absolute;
bottom: -6px;
margin-left: -7px;
left: 50%;
}
.tooltip-static:before {
border-top-color: #ffcc33;
}
.map {
height: 50%;
width: 70%;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<form class="form-inline">
<label>Measure: </label>
<select id="type">
<option value="length">Length (LineString)</option>
<option value="area">Area (Polygon)</option>
</select>
</form>
<script>
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source,
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2
}),
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
})
})
})
});
/**
* Currently drawn feature.
* @type {ol.Feature}
*/
var sketch;
/**
* The help tooltip element.
* @type {Element}
*/
var helpTooltipElement;
/**
* Overlay to show the help messages.
* @type {ol.Overlay}
*/
var helpTooltip;
/**
* The measure tooltip element.
* @type {Element}
*/
var measureTooltipElement;
/**
* Overlay to show the measurement.
* @type {ol.Overlay}
*/
var measureTooltip;
/**
* Message to show when the user is drawing a polygon.
* @type {string}
*/
var continuePolygonMsg = 'Click to continue drawing the polygon';
/**
* Message to show when the user is drawing a line.
* @type {string}
*/
var continueLineMsg = 'Click to continue drawing the line';
/**
* Handle pointer move.
* @param {ol.MapBrowserEvent} evt The event.
*/
var pointerMoveHandler = function(evt) {
if (evt.dragging) {
return;
}
/** @type {string} */
var helpMsg = 'برای اندازه گیری کلیک کنید';
if (sketch) {
var geom = (sketch.getGeometry());
if (geom instanceof ol.geom.Polygon) {
helpMsg = continuePolygonMsg;
} else if (geom instanceof ol.geom.LineString) {
helpMsg = continueLineMsg;
}
}
helpTooltipElement.innerHTML = helpMsg;
helpTooltip.setPosition(evt.coordinate);
helpTooltipElement.classList.remove('hidden');
};
var map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([51.39, 35.70]),
zoom: 15
}),
interactions: ol.interaction.defaults({ altShiftDragRotate:false, pinchRotate:false })
});
map.on('pointermove', pointerMoveHandler);
map.getViewport().addEventListener('mouseout', function() {
helpTooltipElement.classList.add('hidden');
});
var typeSelect = document.getElementById('type');
var draw; // global so we can remove it later
/**
* Format length output.
* @param {ol.geom.LineString} line The line.
* @return {string} The formatted length.
*/
var formatLength = function(line) {
var length = ol.Sphere.getLength(line);
var output;
if (length > 100) {
output = (Math.round(length / 1000 * 100) / 100) +
' ' + 'km';
} else {
output = (Math.round(length * 100) / 100) +
' ' + 'm';
}
return output;
};
/**
* Format area output.
* @param {ol.geom.Polygon} polygon The polygon.
* @return {string} Formatted area.
*/
var formatArea = function(polygon) {
var area = ol.Sphere.getArea(polygon);
var output;
if (area > 10000) {
output = (Math.round(area / 1000000 * 100) / 100) +
' ' + 'km<sup>2</sup>';
} else {
output = (Math.round(area * 100) / 100) +
' ' + 'm<sup>2</sup>';
}
return output;
};
function addInteraction() {
var type = (typeSelect.value == 'area' ? 'Polygon' : 'LineString');
draw = new ol.interaction.Draw({
source: source,
type: type,
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 0, 0.5)',
lineDash: [10, 10],
width: 2
}),
image: new ol.style.Circle({
radius: 5,
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 0, 0.7)'
}),
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
})
})
})
});
map.addInteraction(draw);
createMeasureTooltip();
createHelpTooltip();
var listener;
draw.on('drawstart',
function(evt) {
// set sketch
sketch = evt.feature;
/** @type {ol.Coordinate|undefined} */
var tooltipCoord = evt.coordinate;
listener = sketch.getGeometry().on('change', function(evt) {
var geom = evt.target;
var output;
if (geom instanceof ol.geom.Polygon) {
output = formatArea(geom);
tooltipCoord = geom.getInteriorPoint().getCoordinates();
} else if (geom instanceof ol.geom.LineString) {
output = formatLength(geom);
tooltipCoord = geom.getLastCoordinate();
}
measureTooltipElement.innerHTML = output;
measureTooltip.setPosition(tooltipCoord);
});
}, this);
draw.on('drawend',
function() {
measureTooltipElement.className = 'tooltip tooltip-static';
measureTooltip.setOffset([0, -7]);
// unset sketch
sketch = null;
// unset tooltip so that a new one can be created
measureTooltipElement = null;
createMeasureTooltip();
ol.Observable.unByKey(listener);
}, this);
}
/**
* Creates a new help tooltip
*/
function createHelpTooltip() {
if (helpTooltipElement) {
helpTooltipElement.parentNode.removeChild(helpTooltipElement);
}
helpTooltipElement = document.createElement('div');
helpTooltipElement.className = 'tooltip hidden';
helpTooltip = new ol.Overlay({
element: helpTooltipElement,
offset: [15, 0],
positioning: 'center-left'
});
map.addOverlay(helpTooltip);
}
/**
* Creates a new measure tooltip
*/
function createMeasureTooltip() {
if (measureTooltipElement) {
measureTooltipElement.parentNode.removeChild(measureTooltipElement);
}
measureTooltipElement = document.createElement('div');
measureTooltipElement.className = 'tooltip tooltip-measure';
measureTooltip = new ol.Overlay({
element: measureTooltipElement,
offset: [0, -15],
positioning: 'bottom-center'
});
map.addOverlay(measureTooltip);
}
/**
* Let user change the geometry type.
*/
typeSelect.onchange = function() {
map.removeInteraction(draw);
addInteraction();
};
addInteraction();
// Current selection
var sLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
stroke: new ol.style.Stroke ({
color: 'rgb(255,165,0)',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(255,165,0,.3)'
})
}),
stroke: new ol.style.Stroke ({
color: 'rgb(255,165,0)',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(255,165,0,.3)'
})
})
});
map.addLayer(sLayer);
// Set the search control
var search = new ol.control.SearchNominatim (
{ //target: $(".options").get(0),
polygon: $("#polygon").prop("checked"),
position: true // Search, with priority to geo position
});
map.addControl (search);
// Select feature when click on the reference index
search.on('select', function(e)
{ // console.log(e);
sLayer.getSource().clear();
// Check if we get a geojson to describe the search
if (e.search.geojson) {
var format = new ol.format.GeoJSON();
var f = format.readFeature(e.search.geojson, { dataProjection: "EPSG:4326", featureProjection: map.getView().getProjection() });
sLayer.getSource().addFeature(f);
var view = map.getView();
var resolution = view.getResolutionForExtent(f.getGeometry().getExtent(), map.getSize());
var zoom = view.getZoomForResolution(resolution);
var center1 = ol.extent.getCenter(f.getGeometry().getExtent());
// redraw before zoom
setTimeout(function(){
view.animate({
center: center1,
zoom: Math.min (zoom, 16)
});
}, 100);
}
else {
map.getView().animate({
center:e.coordinate,
zoom: Math.max (map.getView().getZoom(),16)
});
}
});
</script>
<div class="options">
<label>
<input id="polygon" type="checkbox" onclick="search.set('polygon', $(this).prop('checked')); search.search();" />
extract polygons<br/>(may slow down requests)
</label>
<br/>
<i>Use the search control to start a new search.</i>
</div>
</body>
</html>