How to display information using Overlay in Openlayers? - javascript

I had a vector in my map with an image but ned to use gif instead static image so i exchanged o.layer.vector for ol.Overlay, it displays my gif but I can't get any way to add it to my layerSwitcher because overlay doesn't have title property, also with vector i could display some information using forEachFeaturePixel but now i cant. Is there any way to add my overlay to layerSwitcher and display information clicking on it?
This is what i had:
lastPoint = new ol.layer.Vector({
source: new ol.source.Vector({
features: [new ol.Feature(
new ol.geom.Point(
ol.proj.fromLonLat(lastCoordinates, map.getView().getProjection())
)
)]
}),
visible: true,
title: "Evento sísmico",
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5],
size: [30, 28],
offset: [0.2, 0.2],
scale: 1,
src: "assets/img/red-point.png"
}),
}),
})
addEarthqPoint = (e, map, clickedCoordinate, date, time, depth, magnitude, overlayLayerEarthq) => {
map.forEachFeatureAtPixel(e.pixel, () => {
overlayLayerEarthq.setPosition(clickedCoordinate);
overlayTitleEarthq.innerHTML = "Detalle de evento: "
overlayFeatureDate.innerHTML = "Fecha: " + date;
overlayFeatureTime.innerHTML = "Hora (UTC-5): " + time;
overlayFeatureDepth.innerHTML = "Profundidad: " + depth + " km";
overlayFeatureMagnitude.innerHTML = "Magnitud: M " + magnitude;
}, {
layerFilter: (layerCandidate) => {
return layerCandidate.get("title") === "Evento sísmico";
}
});
}
mapClicked = (overlayLayer, overlayLayerEarthq) => {
map.on("click", function (e) {
const clickedCoordinate = e.coordinate;
overlayLayer.setPosition(undefined);
overlayLayerEarthq.setPosition(undefined);
/* using preview values to use into function */
addEarthqPoint(e, map, clickedCoordinate, lastDate, lastTime, lastDepth, lastMagnitude, overlayLayerEarthq);
});
}
This is my new Overlay:
lastPoint = new ol.Overlay({
position: ol.proj.fromLonLat(lastCoordinates, map.getView().getProjection()),
positioning: 'center-center',
element: document.getElementById('new-gif'),
stopEvent: false
});
Or is there any better way to use a gif instead an image?

Related

Hide / Remove Specific GoogleMapsOverlay From Google Map

I have used geojson files into google map by multi selection . but when i try to remove overlay , it is not working .this is my code to used for add and remove.
i need to know how to remove selected geojson file from map
var deckOverlay ;
deckOverlay = new deck.GoogleMapsOverlay({
layers: [
new deck.GeoJsonLayer({
id: 'layerId',
data: 'path of geojson file',
filled: true,
pointRadiusMinPixels: 2,
opacity: 0.5,
pointRadiusScale: 2000,
getFillColor: f => (f.properties.COLOR),
wireframe: true,
pickable: true,
}), +
new deck.ArcLayer({
id: 'arcs',
data: Layer_Id,
dataTransform: d => d.features.filter(f => f.properties.scalerank < 4),
getSourcePosition: f => [-0.4531566, 51.4709959], // London
getTargetPosition: f => f.geometry.coordinates,
getSourceColor: [0, 128, 200],
getTargetColor: [200, 0, 80],
getWidth: 1
})
]
});
if (checked) {
deckOverlay.setMap(map); // Set multiple overlays working
}
else {
deckOverlay.setMap(null); // Remove Option Not Working
deckOverlay = null;
}
By using Data Layer .
To load map
map.data.loadGeoJson(Layer_Id);
To Remove Specific Layer
map.data.forEach(function (feature) {
if (feature.getProperty('myprop') == myprop) {
map.data.remove(feature);
}
});
To Remove All Layers
map.data.forEach(function (feature) {
map.data.remove(feature);
});
FYI , use color codes as HEX in json file not RGB or RGBA

Google Maps Api v3 - several Marker hovers with Javascript

I want to set different hovers for different marker icons i use on my map.
This is my marker icon array
//Marker Icons
var markerIcon = {
unvisitedMarker: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(15, 15)
},
unvisitedMarkerHover: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(30, 0),
anchor: new google.maps.Point(15, 15)
},
activeMarker: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(60, 0),
anchor: new google.maps.Point(15, 15)
},
visitedMarker: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(90, 0),
anchor: new google.maps.Point(15, 15)
},
visitedMarkerHover: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(120, 0),
anchor: new google.maps.Point(15, 15)
}
I got all icons in one sprite.
I want to set the hover effect for the 'unvisitedMarker' with 'unvisitedMarkerHover' and for 'visitedMarker with 'visitedMarkerHover'. If the marker has the 'activeMarker' icon it should not get a hover effect.
My Problem with this is - i don't know how to set the "if" requirement for that.
//marker hover effect
marker.addListener('mouseover', function() {
if (???) { ... }
});
marker.addListener('mouseout', function() {
if (???) { ... }
});
After that i know i can set the icon with:
marker.setIcon(markerIcon['unvisitedMarker']);
So if someone could help me with the if requirement - that would be awesome!
This one is not that simple. Since I don't have the details such as the URL to your images, I created a sample application in which we have at least 90% similarity. Important: Please don't use the images I've used to avoid copyright issues.
First, I've created public variables: map, markers. "markers" is an empty array.
var map;
var markers = [];
I've also created my own version of markerIcon object.
var markerIcon = {
url : 'http://oi68.tinypic.com/30idv0z.jpg',
unvisitedMarkerHover: 'http://oi65.tinypic.com/jgo3r8.jpg',
originlUrl: 'http://oi68.tinypic.com/30idv0z.jpg',
visitedMarkerHover: 'http://oi65.tinypic.com/ejbn88.jpg',
status: {
unvisitedMarker : {
statusName: 'unvisitedMarker',
},
activeMarker : {
statusName: 'activeMarker',
},
visitedMarker : {
statusName: 'visitedMarker',
}
}
};
I've used a coordinate in San Francisco for my map's center and for Google Maps Javascript API Places Library. I've used Nearby Search as a Place Search and used San Francisco's coordinate for the location property. The radius is set to 500 (measured in meters). This is essential as a combination of the location property - specifying the center of the circle as a LatLng object. For the types, i restricted it only to stores. To learn more about supported types, please check list of supported types.
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: myLatLng,
radius: '500',
type: ['store']
}, callback);
In Nearby Search callback, it returns an array of results. This is what I did:
function createMarker(place, markerId) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
id: markerId,
map: map,
position: placeLoc,
title: 'Hello World!',
anchor: new google.maps.Point(15, 15),
icon: {
url : markerIcon.url,
},
currentStatus: '',
status: markerIcon.status.unvisitedMarker.statusName,
size: new google.maps.Size(30,30),
});
markers.push(marker);
}
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i],i);
}
}
}
I created a createMarker() function that accepts two arguments: the
place object, and markerId.
What the function does is it creates a new Google Maps Javascript
API
Marker
and then set the property and its values accordingly. And also, after
creating the new "marker" object, it will be pushed in to
markers array.
You will also notice that I've added custom properties:
currentStatus, and status. This will play a very important role in
our mouse events.
Since the callback results is an array, I iterate through each array
and called createMarker() function.
This is where the fun begins, in createMarker(), I've also added lines for Google Maps Javascript API Events. This is what I did on my end. Whenever there's a mouseover on a marker, it checks first the currentStatus property of the mouseovered marker. If the currentStatus is an empty string '', it will do another checking for the status property. If the status is 'unvisited', the current icon will now change to a new one. When a mouseout has been detected, the new icon will change to the original one.
Meanwhile, when a marker is clicked, the currentStatus property will be updated to "activeMarker" and then the "status" property is changed to "visitedMarker" as well. You will notice that if the marker has an "activeMarker" currentStatus, nothing will happen when there's a mouseover.
In order to remove the "activeMarker" currentStatus, you will have to click another marker. The "activeMarker" now is transferred to this "another marker". You will also notice that there's a new mouseover effect on the previous marker because I've set a new icon if the marker's status is "unvisitedMarker". You can all find all icon URLs in the markerIcon object.
google.maps.event.addListener(marker, 'mouseover', function() {
if ( this.currentStatus !== markerIcon.status.activeMarker.statusName ) {
if ( this.status === markerIcon.status.unvisitedMarker.statusName ) {
this.setIcon(markerIcon.unvisitedMarkerHover);
} else {
this.setIcon(markerIcon.visitedMarkerHover);
}
this.setPosition(this.position);
console.log(this.currentStatus, this.status, this.id);
}
});
google.maps.event.addListener(marker, 'mouseout', function() {
this.setIcon(markerIcon.originlUrl);
});
google.maps.event.addListener(marker, 'click', function() {
for ( var i = 0; i < markers.length; i++ ) {
markers[i].currentStatus = '';
}
this.currentStatus = markerIcon.status.activeMarker.statusName;
this.status = markerIcon.status.visitedMarker.statusName;
console.log(this.currentStatus, this.status);
});
Whole code below:
var map;
var markers = [];
var markerIcon = {
url : 'http://oi68.tinypic.com/30idv0z.jpg',
unvisitedMarkerHover: 'http://oi65.tinypic.com/jgo3r8.jpg',
originlUrl: 'http://oi68.tinypic.com/30idv0z.jpg',
visitedMarkerHover: 'http://oi65.tinypic.com/ejbn88.jpg',
status: {
unvisitedMarker : {
//origin: new google.maps.Point(0, 0),
statusName: 'unvisitedMarker',
},
activeMarker : {
//origin: new google.maps.Point(60, 0),
statusName: 'activeMarker',
},
visitedMarker : {
//origin: new google.maps.Point(90, 0),
statusName: 'visitedMarker',
},
}
};
function initMap() {
var myLatLng = {lat: 37.773972, lng: -122.431297};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: myLatLng
});
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: myLatLng,
radius: '500',
type: ['store']
}, callback);
}
function createMarker(place, markerId) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
id: markerId,
map: map,
position: placeLoc,
title: 'Hello World!',
anchor: new google.maps.Point(15, 15),
icon: {
url : markerIcon.url,
},
currentStatus: '',
status: markerIcon.status.unvisitedMarker.statusName,
size: new google.maps.Size(30,30),
});
markers.push(marker);
google.maps.event.addListener(marker, 'mouseover', function() {
if ( this.currentStatus !== markerIcon.status.activeMarker.statusName ) {
if ( this.status === markerIcon.status.unvisitedMarker.statusName ) {
this.setIcon(markerIcon.unvisitedMarkerHover);
} else {
this.setIcon(markerIcon.visitedMarkerHover);
}
this.setPosition(this.position);
//console.log(this.currentStatus, this.status, this.id);
}
});
google.maps.event.addListener(marker, 'mouseout', function() {
this.setIcon(markerIcon.originlUrl);
});
google.maps.event.addListener(marker, 'click', function() {
for ( var i = 0; i < markers.length; i++ ) {
markers[i].currentStatus = '';
}
this.currentStatus = markerIcon.status.activeMarker.statusName;
this.status = markerIcon.status.visitedMarker.statusName;
});
}
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i],i);
}
}
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyCzjs-bUR6iIl8yGLr60p6-zbdFtRpuXTQ&callback=initMap"
async defer></script>
Hope this application could help and happy coding!

How to change image color in openlayers3?

I am new to openlayers3. I am showing point as a image but I want to change color of image dynamically.Is it possible in openlayers3 or have any other facility like canvas in openlayers3?
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'data/icon.png'
}))
});
Taking Icon Colors as starting point where they use a transparent PNG with ol.Color option to have multiple color dots I've tried to change the colors like this without success...
var london = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-0.12755, 51.507222]))
});
london.setStyle(new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
color: '#ff0000',
crossOrigin: 'anonymous',
src: 'https://openlayers.org/en/v4.1.1/examples/data/dot.png'
}))
}));
var vectorSource = new ol.source.Vector({
features: [london]
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
var rasterLayer = new ol.layer.Tile({
source: new ol.source.TileJSON({
url: 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json?secure',
crossOrigin: ''
})
});
var map = new ol.Map({
layers: [rasterLayer, vectorLayer],
target: document.getElementById('map'),
view: new ol.View({
center: ol.proj.fromLonLat([2.896372, 44.60240]),
zoom: 3
})
});
map.on('singleclick', function (event) { // Use 'pointermove' to capture mouse movement over the feature
map.forEachFeatureAtPixel(event.pixel, function (feature, layer) {
/* Get the current image instance and its color */
var image = feature.getStyle().getImage();
console.log(image.getColor());
/* Color gets stored in image.i, but there's no setter */
console.log(image.i);
/* Trying to force the color change: */
image.i = [0, 255, 0, 1];
/* Dispatch the changed() event on layer, to force styles reload */
layer.changed();
console.log(image.getColor()); // Logs new color, but it doesn't work...
});
});
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v4.1.1/build/ol.js"></script>
<div id="map" class="map"></div>
See how you can retrieve an icon's color like this:
var image = feature.getStyle().getImage(),
color = image.getColor(); // returns [R, G, B, alpha]
but there's no setColor() method, so there's no way to change the color in runtime...
EDIT: Reviewing again your question and your code, I've noticed you never set a color for your icon, so maybe you don't really want to actually change the color in response to an event but just set a color. If that's what you want, then it's easy:
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'data/icon.png',
color: '#ff0000' // allows HEX as String or RGB(a) as Array
}))
});
See: http://openlayers.org/en/latest/apidoc/ol.style.Icon.html

OpenLayers-3 - What is the correct usage of source.clear()

I have a ol 3.10.1 map where the goal is to redraw the features of a layer dynamically. On the road to get there, I'm using the source.clear() function. The strange thing is that the source.clear() actually clear the features from the layer at the current zoom level, but while zooming in or out the features are still there. Am I using the source.clear() function the correct way? Please find bellow the code snippet which I'm using for testing purposes.
var image = new ol.style.Circle({
radius: 5,
fill: null,
stroke: new ol.style.Stroke({color: 'red', width: 1})
});
var styles = {
'Point': [new ol.style.Style({
image: image
})]};
var styleFunction = function(feature, resolution) {
return styles[feature.getGeometry().getType()];
};
var CITYClusterSource = new ol.source.Cluster({
source: new ol.source.Vector({
url: 'world_cities.json',
format: new ol.format.GeoJSON(),
projection: 'EPSG:3857'
}),
})
var CITYClusterLayer = new ol.layer.Vector({
source: CITYClusterSource,
style: styleFunction
});
setTimeout(function () { CITYClusterSource.clear(); }, 5000);
var map = new ol.Map({
target: 'map',
renderer: 'canvas',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
}),
CITYClusterLayer
],
view: new ol.View({
center: ol.proj.transform([15.0, 45.0], 'EPSG:4326', 'EPSG:3857'),
zoom:3
})
});
I'm using the setTimout() function to have the features visible for some seconds, before they are supposed to be cleared.
Please advice.
UPDATE: http://jsfiddle.net/jonataswalker/ayewaz87/
I forgot, OL will load your features again and again, for each resolution. So if you want to remove once and for all, use a custom loader, see fiddle.
Your source is asynchronously loaded, so set a timeout when it's ready:
CITYClusterSource.once('change', function(evt){
if (CITYClusterSource.getState() === 'ready') {
// now the source is fully loaded
setTimeout(function () { CITYClusterSource.clear(); }, 5000);
}
});
Note the once method, you can use on instead of it.

OpenLayers 3 Polymer 1.0 module

I'm trying to make a Polymer module for working with OpenLayers 3 and displaying openstreetmaps. I know there is a great module working with leaflet but I need some specifics functions like map orientation.
Anyway, I code something and it's working except one thing I can't figure out : When the page loads, only the commands are showing (Zoom + / Zoom -) and not the map (and not any thing such as marker, etc). But if I resize my window (my Chrome window I mean) the map appear and all is working fine !! I was thinking maybe something in relation with DOM Loading...
Module code :
<dom-module id="openlayer-map">
<link rel="stylesheet" href="http://openlayers.org/en/v3.7.0/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.7.0/build/ol.js" type="text/javascript"></script>
<style>
:host {
display: block;
}
#map
{
position: absolute;
height: 100%;
}
</style>
<template>
<div id="map" class="map"></div>
<!-- Tests
<input is="iron-input" bind-value="{{latitude}}" placeholder="latitude">
<input is="iron-input" bind-value="{{longitude}}" placeholder="longitude">
-->
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'openlayer-map',
properties:
{
currentCenter: Array,
currentView: ol.View,
olmap: ol.Map,
geolocation: ol.Geolocation,
layer: Object,
longitude:
{
type: Number,
value:12.889101100000062,
notify: true,
observer: '_updateLongitude'
},
latitude:
{
type: Number,
value: 15.7622695,
notify: true,
observer: '_updateLatitude'
},
geotracking:
{
value: false,
type: Boolean,
notify: true,
},
elemReady: Boolean,
},
ready: function()
{
console.log('openlayer-map ready');
this.initialConfig();
this.elemReady = true;
this.setCenter(this.latitude,this.longitude);
},
initialConfig: function()
{
console.log('initial config for the map...');
this.currentView = new ol.View({
zoom: 14
});
var source = new ol.source.OSM();
this.layer = new ol.layer.Tile();
this.layer.setSource(source);
this.olmap = new ol.Map({
layers: [this.layer],
target: this.$.map,
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: this.currentView
});
// Localisation
this.geolocation = new ol.Geolocation({
projection: this.currentView.getProjection()
});
this.geolocation.setTracking(this.geotracking);
if(this.geolocation)
{
var accuracyFeature = new ol.Feature();
this.geolocation.on('change:accuracyGeometry', function() {
accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
}.bind(this));
var positionFeature = new ol.Feature();
positionFeature.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: '#3399CC'
}),
stroke: new ol.style.Stroke({
color: '#fff',
width: 2
})
})
}));
this.geolocation.on('change:position', function() {
var coordinates = this.geolocation.getPosition();
positionFeature.setGeometry(coordinates ?
new ol.geom.Point(coordinates) : null);
}.bind(this));
var featuresOverlay = new ol.layer.Vector({
map: this.olmap,
source: new ol.source.Vector({
features: [accuracyFeature, positionFeature]
})
});
}
},
_updateLatitude: function(newValue, oldValue)
{
if(this.elemReady)
{
console.log('update latitude from '+oldValue+' to '+newValue);
this.setCenter(newValue, this.longitude);
}
else
{
console.log('_updateLatitude: waiting element to be ready');
}
},
_updateLongitude: function(newValue, oldValue)
{
if(this.elemReady)
{
console.log('update longitude from '+oldValue+' to '+newValue);
this.setCenter(this.latitude, newValue);
}
else
{
console.log('_updateLatitude: waiting element to be ready');
}
},
setCenter: function(latitude, longitude)
{
var center = [longitude, latitude];
this.currentCenter = ol.proj.fromLonLat(center);
console.log('update center of the map with latitude = '+latitude+' and longitude = '+longitude);
this.currentView.centerOn(this.currentCenter,[400,400], [0,0]);
},
});
})();
</script>
And the call in Polymer :
<openlayer-map latitude="48.853" longitude="2.35" geotracking></openlayer-map>
Any clue ?
Found it ! Needed to do the map initialization in an asynchronous call
attached: function()
{
this.async(function()
{
this.initialConfig(); // Create your ol.Map here
});
},

Categories