I have located a point on a map
var layer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat(cord)),
label: 'Label'
})
]
}),
style: (feature) => {
myStyle.getText().setText(feature.get('label'));
return [myStyle];
}
});
I just wanted to make a link to the label (or the point) that takes me to another page. Any help.
Put a click event handler on your map and use getFeaturesAtPixel to find the feature (if any) that has been clicked on. For example:
map.on("click", (event) => {
const features = map.getFeaturesAtPixel(event.pixel);
if (features && features.length > 0) {
// ...
}
});
Related
i want to import my shapefile into my map using openlayers Bing.Map but after import my shape file in map i can not zoom out or zoom in in my map and it looks like crushing
i am using openlayers7.1 in my code . i set drag and drop event for importing shape file in to map . this code can handle shape.shp shape.dbf shape.sbn and ... as shape.zip file
the rest of code can be found https://openlayers.org/en/latest/examples/bing-maps.html here but for working you need to replace your API Key where you can see API Key in the code .
i need Sample code to fix this. thanks
import BingMaps from 'ol/source/BingMaps';
import Map from 'ol/Map';
import TileLayer from 'ol/layer/Tile';
import View from 'ol/View';
import { fromLonLat } from "ol/proj";
import vectorSource from 'ol/source/Vector';
const place =[59.6067,36.2972];
const styles = [
'RoadOnDemand',
'Aerial',
'AerialWithLabelsOnDemand',
'CanvasDark',
'OrdnanceSurvey',
];
const layers = [];
let i, ii;
for (i = 0, ii = styles.length; i < ii; ++i) {
layers.push(
new TileLayer({
visible: false,
preload: Infinity,
source: new BingMaps({
key: "API Key",
imagerySet: styles[i],
// use maxZoom 19 to see stretched tiles instead of the BingMaps
// "no photos at this zoom level" tiles
// maxZoom: 19
}),
})
);
}
const map = new Map({
layers: layers,
target: 'map',
view: new View({
center: fromLonLat(place),
zoom: 8,
}),
});
const select = document.getElementById('layer-select');
function onChange() {
const style = select.value;
for (let i = 0, ii = layers.length; i < ii; ++i) {
layers[i].setVisible(styles[i] === style);
}
}
select.addEventListener('change', onChange);
onChange();
const featureStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 1
})
});
map.getViewport().addEventListener('dragover', function(event) {
event.preventDefault();
});
map.getViewport().addEventListener('drop',shpShow);
function shpShow(event) {
event.preventDefault();
const files = event.dataTransfer.files;
for (let i = 0, ii = files.length; i < ii; ++i) {
const file = files.item(i);
loadshp({url: file, encoding: 'utf-8'}, function(geojson) {
const features = new ol.format.GeoJSON().readFeatures(
geojson,
{ featureProjection: map.getView().getProjection() }
);
const vectorSource = new ol.source.Vector({
features: features
});
map.addLayer(
new ol.layer.Vector({
source: vectorSource,
style: featureStyle
})
);
map.getView().fit(vectorSource.getExtent());
});
}
}
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v6.3.1/build/ol.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/lib/jszip.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/lib/jszip-utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.1/proj4.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/preprocess.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/preview.js"></script>
I presume you are using loadshp from https://github.com/gipong/shp2geojson.js?
A dropped file needs to be read by a FileReader, in your case as a dataUrl
const file = files.item(i);
const reader = new FileReader();
reader.addEventListener('load', function() {
loadshp({url: reader.result, encoding: 'utf-8'}, function(geojson) {
....
....
});
});
reader.readAsDataURL(file);
very good question
When we import the .shp files, the map is not refreshed again.
I had this challenge for a long time and still this problem exists in my codes.
Thanks if anyone has the ability to solve this challenge.
I am new to work with Open layer version 7 api , i want to draw a graph in map with js code which the points are special locations and lines should join those locations
I used this examples , i link them below
I got confused how to do it , i think i should combine them but i couldn't
https://openlayers.org/en/latest/examples/icon-color.html
https://openlayers.org/en/latest/examples/feature-move-animation.html
https://openlayers.org/en/latest/examples/bing-maps.html
https://openlayers.org/en/latest/examples/gpx.html
i want something like this img
i think you should make Gpx file of location you want and then you will be fine
use this example
The following code can read .shp files as zip and display them on the map.
import BingMaps from 'ol/source/BingMaps';
import Map from 'ol/Map';
import TileLayer from 'ol/layer/Tile';
import View from 'ol/View';
import { fromLonLat } from "ol/proj";
import vectorSource from 'ol/source/Vector';
const place =[59.6067,36.2972];
const styles = [
'RoadOnDemand',
'Aerial',
'AerialWithLabelsOnDemand',
'CanvasDark',
'OrdnanceSurvey',
];
const layers = [];
let i, ii;
for (i = 0, ii = styles.length; i < ii; ++i) {
layers.push(
new TileLayer({
visible: false,
preload: Infinity,
source: new BingMaps({
key: "API Key",
imagerySet: styles[i],
// use maxZoom 19 to see stretched tiles instead of the BingMaps
// "no photos at this zoom level" tiles
// maxZoom: 19
}),
})
);
}
const map = new Map({
layers: layers,
target: 'map',
view: new View({
center: fromLonLat(place),
zoom: 8,
}),
});
const select = document.getElementById('layer-select');
function onChange() {
const style = select.value;
for (let i = 0, ii = layers.length; i < ii; ++i) {
layers[i].setVisible(styles[i] === style);
}
}
select.addEventListener('change', onChange);
onChange();
const featureStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 1
})
});
map.getViewport().addEventListener('dragover', function(event) {
event.preventDefault();
});
map.getViewport().addEventListener('drop',shpShow);
function shpShow(event) {
event.preventDefault();
const files = event.dataTransfer.files;
for (let i = 0, ii = files.length; i < ii; ++i) {
const file = files.item(i);
loadshp({url: file, encoding: 'utf-8'}, function(geojson) {
const features = new ol.format.GeoJSON().readFeatures(
geojson,
{ featureProjection: map.getView().getProjection() }
);
const vectorSource = new ol.source.Vector({
features: features
});
map.addLayer(
new ol.layer.Vector({
source: vectorSource,
style: featureStyle
})
);
map.getView().fit(vectorSource.getExtent());
});
}
}
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v6.3.1/build/ol.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/lib/jszip.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/lib/jszip-utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.1/proj4.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/preprocess.js"></script>
<script src="https://gipong.github.io/shp2geojson.js/preview.js"></script>
I'm building a navigation app. I am using openlayers and osm. So far I have drawn the path between 2 points. But since my location is updated every 5 seconds I have to recreate the path. Even when re-creating the path, the old path is not deleted. How can I solve this problem?
var vectorSource = new ol.source.Vector(),
url_osrm_nearest = '//router.project-osrm.org/nearest/v1/driving/',
url_osrm_route = '//router.project-osrm.org/route/v1/driving/',
icon_url = '//cdn.rawgit.com/openlayers/ol3/master/examples/data/icon.png',
vectorLayer = new ol.layer.Vector({
source: vectorSource
}),
styles = {
route: new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6, color: [40, 40, 40, 0.8]
})
}),
icon: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: icon_url
})
})
};
var utils = {
getNearest: function(coord){
var coord4326 =coord;
return new Promise(function(resolve, reject) {
//make sure the coord is on street
fetch(url_osrm_nearest + coord4326.join()).then(function(response) {
// Convert to JSON
return response.json();
}).then(function(json) {
if (json.code === 'Ok') resolve(json.waypoints[0].location);
else reject();
});
});
},
createFeature: function(coord) {
var feature = new ol.Feature({
type: 'place',
geometry: new ol.geom.Point(coord)
});
feature.setStyle(iconStyle2);
vectorSource.addFeature(feature);
},
createRoute: function(polyline) {
var route = new ol.format.Polyline({
factor: 1e5
}).readGeometry(polyline);
var feature = new ol.Feature({
type: 'route',
geometry: route
});
feature.setStyle(styles.route);
vectorSource.addFeature(feature);
},
to4326: function(coord) {
return ol.proj.transform([
parseFloat(coord[0]), parseFloat(coord[1])
]);
}
};
const map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
}),
vectorLayer
],
target: 'map',
view: view,
});
function first_route(data)
{
lati = data.latii;
longi = data.longii;
utils.getNearest([my_longi,my_lati]);
utils.getNearest([longi,longi]);
utils.createFeature([longi,longi]);
var point1 = [my_longi,my_lati];
var point2 = [longi,longi];
fetch(url_osrm_route + point1 + ';' + point2).then(function(r) {
return r.json();
}).then(function(json) {
if(json.code !== 'Ok') {
return;
}
utils.createRoute(json.routes[0].geometry);
});
}
function locate() {
const coordinates = geolocation.getPosition();
iconCar.setGeometry(coordinates ? new ol.geom.Point(coordinates) : null)
if(iconCar.getGeometry() != null)
map.getView().fit(iconCar.getGeometry(),{maxZoom: 16});
if(coordinates != null)
{
my_lati = geolocation.getPosition()[1];
my_longi = geolocation.getPosition()[0];
}
utils.getNearest([my_longi,my_lati]);
utils.getNearest([longi,lati]);
utils.createFeature([longi,lati]);
var point1 = [my_longi,my_lati];
var point2 = [longi,lati];
fetch(url_osrm_route + point1 + ';' + point2).then(function(r) {
return r.json();
}).then(function(json) {
if(json.code !== 'Ok') {
return;
}
utils.createRoute(json.routes[0].geometry);
});
}
setInterval(locate, 14000);
Location is updated every 5 seconds. Therefore, the route on the map also needs to be changed. But when I try to do it this way it doesn't delete the old route. It draws another route on the same route.
If you make the route feature a global variable you can create it, or if it already exists, update it
var routeFeature;
createRoute: function(polyline) {
var route = new ol.format.Polyline({
factor: 1e5
}).readGeometry(polyline);
if (!routeFeature) {
routeFeature = new ol.Feature({
type: 'route',
geometry: route
});
routeFeature.setStyle(styles.route);
vectorSource.addFeature(routeFeature);
} else {
routeFeature.setGeometry(route);
}
},
I'm currently using PlacesService library from Google Maps API. I want to render suggestions for New York City. I added strict_bounds for this matter but I still get results way out of New York as shown in the image.
For the most part it works, but I get many out of bounds suggestions.
/** #private {?this._google.maps.Map} The google map object. */
this._map = new this._google.maps.Map(this._mapEl, {
zoom: 11,
center: this._mapPosition
});
/** #private {this._google.maps.places.Autocomplete}Autocomplete instance */
this._service = new this._google.maps.places.AutocompleteService();
/** #private {this._google.maps.places.PlaceService}PlaceService instance */
this._placeService = new this._google.maps.places.PlacesService(this._map);
Here is the instance in the constructor.
// Attach handler for the autocomplete search box. This updates the map
// position and re-sorts locations around that position.
this._searchEl.addEventListener('keyup', (event) => {
if(event.target.value) {
this._service.getPlacePredictions({
input: event.target.value,
offset: 3,
strictBounds: true,
types: ['geocode'],
bounds: this._map.getBounds()
}, (predictions) => {
if(predictions) {
let results = predictions.map(e => [e['description']]);
event.target.missplete = new MissPlete({
input: event.target,
options: results,
className: 'c-autocomplete'
})
event.target.missplete.select = () => {
let msplt = event.target.missplete;
if (msplt.highlightedIndex !== -1) {
msplt.input.value = msplt
.scoredOptions[msplt.highlightedIndex].displayValue;
msplt.removeDropdown();
console.dir('we did it');
}
};
event.target.predictions = predictions;
console.log(event.target.predictions);
}
});
}
});
There is a method displayPlacesOnMap that gets an array of Google place objects. Here we get the place_id in order to make use of PlaceService library.
displayPlacesOnMap(mapItems) {
if(mapItems) {
mapItems.forEach(place => {
let request = {
placeId: place.place_id,
fields: ['name', 'formatted_address', 'place_id', 'geometry']
}
const officeMap = this;
this._placeService.getDetails(request, function(place, status) {
if (status === 'OK') {
officeMap._mapPosition = place.geometry.location;
officeMap._map.panTo(officeMap._mapPosition);
officeMap.sortByDistance().clearLocations().updateUrl().updateList()
.updateUrl();
$(officeMap._searchEl).blur();
}
})
})
}
};
Attempting to emit a geometry after the feature is drawn on tab 1. Then trying to redraw the feature using socket.on to be displayed on tab 2. however for some reason the feature is not drawn.
window.onload = function init() {
var source = new ol.source.Vector({ wrapX: false });
//create a base vector layer to draw on
var vector = new ol.layer.Vector({
source: source,
});
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
//create map
map = new ol.Map({
layers: [raster, vector],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
center: [0,0],
zoom: 10
})
});
function drawShape(value) {
var value = value;
if (value !== 'None') {
draw = new ol.interaction.Draw({
source: source,
type: /** #type {ol.geom.GeometryType} */ (value)
});
map.addInteraction(draw);
draw.on('drawend', function (event) {
// Get the array of features
var feature = event.feature
try {
map.removeInteraction(draw);
socket.emit('new polygon', feature.getGeometry().getCoordinates());
socket.emit('chat message', feature.getGeometry().getCoordinates());
} catch (err) { }
});
}
}
var socket = io();
socket.on('new polygon', function (msg) {
var thing = new ol.geom.Polygon(msg);
var featurething = new ol.Feature({
name: "Thing",
geometry: thing
});
source.addFeature(featurething);
});
}
when the script is run the msg contains an array of coordinates. Nothing appears in the console.
I am a beginner at node.js. anyone know what i am doing wrong
Found the error. In your socket.on callback you are calling
source.addFeatures(featurething);
when it should be
source.addFeature(featurething); // single feature, no s
or
source.addFeatures([featurething]); // put it in an array