I'm using the Google Maps javascript V3 API and I'm having problems with setting the visibility of a rectangle overlay. Basically, I have a click listener, and inside the listener I have this code:
var neLat = containmentCenter.lat()+ydiff;
var neLng = containmentCenter.lng()+xdiff;
var swLat = containmentCenter.lat()-ydiff;
var swLng = containmentCenter.lng()-xdiff;
nebound = google.maps.LatLng(neLat, neLng);
swbound = google.maps.LatLng(swLat, swLng);
crbounds = google.maps.LatLngBounds(swbound, nebound);
var containRectangleOptions = {
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
map: map,
bounds: crbounds,
editable: true,
visible: true
};
containRectangle.setMap(map);
containRectangle.setOptions(containRectangleOptions);
containRectangle.setVisible(true);
alert("Center: ("+containmentCenter.lat()+","+containmentCenter.lng()+")\nY:
"+ydiff+"\nX: "+xdiff+"\nVisible: "+containRectangle.getVisible());
Where containRectangle is a Rectangle overlay which I define inside of initialize() and above the listener with
containRectangle = new google.maps.Rectangle(defaultRectangleOptions);
defaultRectangleOptions are the exact same as containRectangleOptions except the bounds are map.getBounds() and visible is set to false.
The problem is no rectangle is visible when I click, regardless of the fact that the alert() I have shows the correct coordinates and also correctly says that containRectangle.getVisible() is true. I've also tried having containRectangle be visible in the defaultRectangleOptions but it still doesn't show up. I also have some almost identical code for displaying a circle where I click, and that works exactly correctly, but the rectangle never shows up.
I solved my own problem. I ended up being an error in the way I was initializing the bounds objects. Using the new operator fixed everything.
Related
When I initiate the map I have this listener:
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
console.log('value of e');
console.log(e);
polyArray.push(e);
if (e.type != google.maps.drawing.OverlayType.MARKER) {
// Switch back to non-drawing mode after drawing a shape.
drawingManager.setDrawingMode(null);
}
setMapClickEvent(e.overlay, e.type);
setSelection(e.overlay);
});
Immediatly after this declaration I loop through the current rectangles that should be automatically drawn on the map. This is the code:
_.each($scope.currentRactangles, function(arr) {
new google.maps.Rectangle({
strokeColor: '#002288',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#333322',
fillOpacity: 0.35,
map: map,
editable: true,
bounds: new google.maps.LatLngBounds(
new google.maps.LatLng(arr.upper_lat, arr.upper_lng),
new google.maps.LatLng(arr.lower_lat, arr.lower_lng)
)
});
});
Now, when map is loaded, the existing rectangles (fetched from database) are drawn on the map.
However, the listener never gets triggered.
If I manually draw a rectangle, the I can see in the console "value of e" and the event itself.
My question is: is it possible to trigger the listener when drawing rectangles programmatically?
All this because when I store the rectangles in database, I will store stuff inside the array "polyArray". Which only contains rectangles created manually.
Ok, solution was about storing in the array the newly created rectangles. Basically this snippet:
var tmprect = new google.maps.Rectangle({
strokeColor: '#002288',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#333322',
fillOpacity: 0.35,
map: map,
editable: true,
bounds: new google.maps.LatLngBounds(
new google.maps.LatLng(arr.upper_lat, arr.upper_lng),
new google.maps.LatLng(arr.lower_lat, arr.lower_lng)
)
});
var newrect = {};
newrect.type = 'rectangle';
newrect.overlay = tmprect;
polyArray.push(newrect);
Even if the rectangles from database didn't generated an event they are now inside the same array that will also contain the rectangles manually drawn. That was enough for me as I only needed a way to store rectangles both from user and the automatically generated.
hi i have i one question for polygon and marker, i have more then 50 polygon in map with its id now i want when i search address and put marker on map then i want to get that polygon id where marker is place
this is my code for drop polygon in map
var polyline = new google.maps.Polygon({
paths: objArray,
strokeColor: 'green',
id:zoneid,
strokeOpacity: 1.0,
strokeWeight: 3,
draggable: false,
editable: false
});
polyline.setMap(map);
i use this map for dispaly marker on polygone
when i put marker on polygon then i want to get that polygon id
if you have any example or proper solution then please send me
Use the geometry library. Firstly specify that as a parameter when loading in the JS:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
Then when you create a marker, use its coordinates and check if it's in each of your polygons. You probably want to put each polygon into an array that you can loop over.
var markerCoords = marker.getPosition();
for (var i = 0; i < polygons.length; i++) {
if (google.maps.geometry.poly.containsLocation(markerCoords, polygons[i])) {
var id = polygons[i].id;
break;
}
}
See:
https://developers.google.com/maps/documentation/javascript/geometry#containsLocation
https://developers.google.com/maps/documentation/javascript/examples/poly-containsLocation
I am using the Maps API v3 and added a GeoJSON file to create a circle (based on google.maps.Symbol objects) around each entry in the GeoJSON-file -- which works quite fine by using the setStyle-functionality:
map.data.addGeoJson('url_to_GeoJSON');
..
map.data.setStyle(function(feature) {
return /** #type {google.maps.Data.StyleOptions} */({
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 5,
fillColor: '#f00',
fillOpacity: 0.5,
strokeWeight: 0
}
});
});
Now I would need to draw a circle with a static radius in meters around each point, like it is provided by the regular google.maps.CircleOptions with its 'radius'.
Is there any possibility to use the very comfortable data layer 'addGeoJson'- and 'setStyle'-features in combination with a geographically correct radius in meters around each point?
I would be very happy to avoid setting up each marker manually "the old way" by iterating through the whole GeoJSON-file with
new google.maps.Circle({radius: 20000});
Any help is greatly appreciated! Thanks in advance!
After adding the code of Dr. Molle, there seems to be an issue while using multiple google.maps.Data-Objects, that should be shown/hide by checking/unchecking a checkbox within the website. This is my actual code, which already shows the data layer with drawn circles, but does not hide the circles of the specific data layer when unchecking a checkbox:
var map;
var dataset1 = new google.maps.Data();
var dataset2 = new google.maps.Data();
var dataset3 = new google.maps.Data();
function initialize() {
// Create a new map.
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 6,
center: {lat: 50.678240, lng: 9.437256},
mapTypeId: google.maps.MapTypeId.TERRAIN
});
checkDataset();
}
function checkDataset() {
if (document.getElementById('chkDataset1').checked) {
// Define styles for dataPlug9 and apply to map-object.
dataset1.setStyle(function(feature) {
var geo = feature.getGeometry();
// Check for a point feature.
if(geo.getType().toLowerCase()==='point'){
//create a circle
feature.circle = new google.maps.Circle({
map: map,
center: geo.get(),
radius: 200000,
fillColor: '#FF0000',
fillOpacity: 0.05,
strokeColor: '#FF0000',
strokeOpacity: 0.4,
strokeWeight: 1
});
//trigger the dblclick-event of map.data on a dblclick on the circle
google.maps.event.addListener(feature.circle, 'dblclick',function(e){
e.stop();
google.maps.event.trigger(this.getMap().data,'dblclick', {feature:feature})
});
// Hide the marker-icon.
return {visible:false};
}});
// Remove feature on dblclick.
google.maps.event.addListener(dataset1,'dblclick',function(f){
this.remove(f.feature);
});
// Remove circle too when feature will be removed.
google.maps.event.addListener(dataset1,'removefeature',function(f){
try{f.feature.circle.setMap(null);}catch(e){}
});
dataset1.loadGeoJson('data/plug1.json');
dataset1.setMap(map);
} else {
dataset1.removefeature();
// This doesn't work either ..
dataset1.setMap(null);
}
}
I also added the above routine of function checkDataset() for the other 2 datasets (dataset2 and dataset3) and changed 'dataset1' to 'dataset2 / dataset3'.
You don't need to iterate "manually", setStyle already iterates over the features.
You may use it to execute additional code(e.g. create a google.maps.Circle):
map.data.setStyle(function(feature) {
var geo= feature.getGeometry();
//when it's a point
if(geo.getType().toLowerCase()==='point'){
//create a circle
feature.circle=new google.maps.Circle({map:map,
center: geo.get(),
radius: 20000,
fillColor: '#f00',
fillOpacity: 0.5,
strokeWeight: 0});
//and hide the marker when you want to
return {visible:false};
}});
Edit:
related to the comment:
The circles will be saved as a circle-property of the features(note: this property is not a property in the meaning of geoJSON, so it may not be accessed via getProperty).
You may add a listener for the removefeature-event and remove the circle there, so the circle will be removed when you remove the feature.
Sample code that will remove a feature(including the circle) on dblclick:
map.data.setStyle(function(feature) {
var geo= feature.getGeometry();
//when it's a point
if(geo.getType().toLowerCase()==='point'){
//create a circle
feature.circle=new google.maps.Circle({map:map,
center:geo.get(),
radius:200000,
fillColor: '#f00',
fillOpacity: 0.5,
strokeWeight: 0});
//trigger the dblclick-event of map.data on a dblclick on the circle
google.maps.event.addListener(feature.circle, 'dblclick',function(e){
e.stop();
google.maps.event.trigger(this.getMap().data,'dblclick',{feature:feature})
});
//and hide the marker
return {visible:false};
}});
//remove the feature on dblclick
google.maps.event.addListener(map.data,'dblclick',function(f){
this.remove(f.feature);
});
//remove the circle too when the feature will be removed
google.maps.event.addListener(map.data,'removefeature',function(f){
try{f.feature.circle.setMap(null);}catch(e){}
});
I created some google.maps.Marker and did bind google.maps.Circle to it (see below):
But when I open street view, I see only Marker:
Does anybody know how to show Circle in street view mode?
Sounds like I can't do that.
Maybe someone knows how to show 2D/3D objects into Google-Street-View.
Any suggestion?
Thanks,
This is snippets of code:
var circle = {
strokeColor: "#006DFC",
strokeOpacity: 0.4,
strokeWeight: 2,
fillColor: "#006DFC",
fillOpacity: 0.15,
map: mapA,
center: selectedMarker.getPosition(),
radius: 50 // in meters
};
var cityCircle = new google.maps.Circle(circle);
cityCircle.bindTo('center', selectedMarker, 'position');
You could use a Symbol instead of a google.maps.Circle to draw the circle, it will be visible on the panorama.
Getting a 3D-effect would be more complicated, but it should be possible to modify the path of the symbol on the pov_changed-event of the panorama.
I have a popup that I'm declaring like so in OpenLayers:
var feature = new O[penLayers.Feature(markers, lonLat);
feature.popupClass = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {
'autoSize': true;
'maxSize': new OpenLayers.Size(500, 300)
});
The issue is that the multiple popups on my map are being created with consecutive z-indexes, so the popups will always be shown in the order the markers were added, with the popup of the most recent marker always being on top.
Is there a way to change it so that the most recently-clicked marker popup is on top, instead of that of the most recently-added marker? I've tried manually changing the z-index in firebug (as a test) but it doesn't bring it to the front. I'd rather avoid deleting and remaking the popup or marker, but it seems to be the only solution I can find.
You can use jQuery to make the trick of the zindex like this
clientesLayer = new OpenLayers.Layer.Vector("PuntosVentas");
feature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(vectorFatri.puntos[index][0],vectorFatri.puntos[index][1]),
{description: '<div><div class="popup_title"><h4>'+vectorFatri.imei+'</h4></div><div class="popup_content">'+vectorFatri.fecha[index]+'</div></div>'} ,
{
strokeColor: "#00FF00",
strokeOpacity: 1,
strokeWidth: 2,
fillColor: "#FF5500",
fillOpacity: 0.5,
pointRadius: 6,
pointerEvents: "visiblePainted"
}
);
controls = {
selector: new OpenLayers.Control.SelectFeature(clientesLayer, {
onSelect: function (feature) {
feature.popup = new OpenLayers.Popup.FramedCloud("pop",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(300,200),
'<div class="markerContent">'+feature.attributes.description+'</div>',
null,
true,
function() { controls['selector'].unselectAll(); }
);
map.addPopup(feature.popup);
{# console.log('me seleccionaron');#}
//jquery trick to make the popup front of everything
$(".olPopup").css("z-index", 10000)
{# setTimeout(function(){$(".olPopup").css("z-index", 10000);}, 2000);#}
},
onUnselect: function (feature) {
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
})
}
map.addControl(controls['selector']);
controls['selector'].activate();
clientesLayer.addFeatures(feature);
I couldn't figure out how to reliably change the z-index and have it work, but I was able to solve my problem by completely removing and then creating a new clone of the map marker when I wanted it in the front.
call ms.setZIndex(100000); where ms is the container of the marker (an instance of OpenLayers.Layer.Markers);