How to make a resizable circle in google maps v3? - javascript

I have the following code, the circle is already moveable, now I want it to be resizeable:
function init() {
var mapCenter = new google.maps.LatLng(0, 0);
var map = new google.maps.Map(document.getElementById('map'), {
'zoom': 1,
'center': mapCenter,
'mapTypeId': google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(55, 0),
draggable: true,
title: 'Drag me!'
});
var circle = new google.maps.Circle({
map: map,
radius: 3000000 // 3000 km
});
circle.bindTo('center', marker, 'position');
}
// Register an event listener to fire when the page finishes loading.
google.maps.event.addDomListener(window, 'load', init);
Now, how can I do the resizer? I already read: http://code.google.com/intl/pt-BR/apis/maps/articles/mvcfun.html
But there isn't another way to do that?

The google.maps.Circle object has method .setEditable(true). The description from the docs says:
If set to true, the user can edit this circle by dragging the control
points shown at the center and around the circumference of the circle.

Related

How to change the default Marker used in the Google Maps API Drawing Layer controls

I would like to know how could I use a custom marker with google maps drawing controls. I want to do that because I need to place a marker when a user clicks in the map and have it open a info window (when clicked) and have a few custom actions in there (buttons and such).
I'm using react and #react-google-maps/api for this, but that might be besides the point since it is just a wrapper around the Maps Javascript API provided by Google.
From the docs it is possible to provide google.maps.MarkerOptions to the google.maps.drawing.DrawingManagerOptions. Unfortunately there is no option there to provide a custom Marker to be rendered.
I tried using the markercomplete() call back exposed by the google.maps.drawing.DrawingManager since it has the newly created Marker as parameter, and then doing something like this:
const handleNewMarker = (marker) => {
marker.addListener('click', function() {
setActiveMarker(marker);
});
}
My map component would then be something like this:
<GoogleMap
zoom={18}
center={latLng}
>
{activeMarker && <CustomInfoWindow anchor={activeMarker} />}
<DrawingManager
options={{
markerOptions: {
clickable: true,
draggable: true,
},
}}
onMarkerComplete={handleNewMarker}
/>
</GoogleMap>
Although this worked, it is not at all viable for production, for some reason the InfoWindow takes too much time to appear in the screen, that approach might be causing a memory leak and I don`t know why.
I might be missing something here, but on my research I didn't find a single soul trying to create a custom marker with the drawing tool, just custom markers by themselves which is relatively easy to do. My ideal case scenario, since I'm using React, would be to create a CustomMarker component with a CustomInfoWindow inside it, and just tell the drawing controls, "hey, take this marker and use it whenever a user tries to draw a new marker with your drawing tool".
Thank you.
Edit
Here is a screenshot of what I mean, that marker in the screen shot was placed there using the "new marker" drawing control, and I need the "new marker" drawing control to place a custom marker defined by me.
All you need to do is to set the icon property in the MarkerOptions, if I correctly understand your meaning of "custom marker". Below is an example using a SVG path for the icon.
This snippet is in full JS but the same should work with the React library.
var map;
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [google.maps.drawing.OverlayType.MARKER]
},
markerOptions: {
draggable: false,
icon: {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: '#FF0000',
fillOpacity: 0.6,
anchor: new google.maps.Point(0, 0),
strokeWeight: 0,
scale: 1
}
}
});
drawingManager.setMap(map);
}
#map {
height: 180px;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize&libraries=drawing" async defer></script>
Now if you need the marker to be clickable, have an Infowindow, etc. do you really need to use the drawing manager? Could you not simply listen for a map click event, and create a standard marker?
Or possibly, use both? (Create the marker with the drawing manager and convert it to a standard marker by the use of the markercomplete event, which seems to be more or less what you are doing.)
Edit:
If you need to create a "real" marker with an InfoWindow, you can do it in the markercomplete event.
var map;
var infowindow;
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
infowindow = new google.maps.InfoWindow();
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [google.maps.drawing.OverlayType.MARKER]
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'markercomplete', function(marker) {
// Remove overlay from map
marker.setMap(null); // Optional, but this will remove the drawn marker
drawingManager.setDrawingMode(null); // Optional, but this will "disable" the drawing tools
// Create the "real" marker
createMarker(marker.getPosition());
});
}
function createMarker(position) {
var marker = new google.maps.Marker({
position: position,
map: map,
title: 'Custom marker',
icon: {
path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
fillColor: '#FF0000',
fillOpacity: 0.6,
anchor: new google.maps.Point(0, 0),
strokeWeight: 0,
scale: 1
}
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('This is the content');
infowindow.open(map, this);
});
}
#map {
height: 180px;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize&libraries=drawing" async defer></script>

Adding Google Maps InfoWindow from data features generates error: "b.get is not a function"

I'm trying to add a info window to each of my features in a Google Map. In the example from Google (https://developers.google.com/maps/documentation/javascript/infowindows) They add an info window directly to a marker. I don't have a explicit market to add my info window, instead I have a collection of data that I imported from a GeoJson file.
I can add a click listener to each feature, and create a new InfoWindow with the correct description. However, I get an error (b.get is not a function) when opening the InfoWindow.
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(28.7, -15.0),
mapTypeId: 'terrain'
});
map.data.loadGeoJson('http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_week.geojson');
map.data.setStyle(function (feature) {
var magnitude = feature.getProperty('mag');
return {
icon: getCircle(magnitude)
};
});
map.data.addListener('click', function (event) {
var infowindow = new google.maps.InfoWindow({
content: event.feature.getProperty('place')
});
infowindow.open(map, event.feature);
});
The error I get with the posted code (once I include all the missing pieces) is Uncaught TypeError: b.get is not a function
The second parameter of the InfoWindow.open method is required to be a MVCObject that exposes a LatLng position property, the only one of which in the core API is a google.maps.Marker (not a event.feature)
from the documentation:
open(map?:Map|StreetViewPanorama, anchor?:*) | Return Value: None
Opens this InfoWindow on the given map. Optionally, an InfoWindow can be associated with an anchor. In the core API, the only anchor is the Marker class. However, an anchor can be any MVCObject that exposes a LatLng position property and optionally a Point anchorPoint property for calculating the pixelOffset (see InfoWindowOptions). The anchorPoint is the offset from the anchor's position to the tip of the InfoWindow.
The work around is to set the position of the InfoWindow:
map.data.addListener('click', function(event) {
var infowindow = new google.maps.InfoWindow({
content: event.feature.getProperty('place')
});
infowindow.setPosition(event.latLng);
infowindow.open(map);
});
proof of concept fiddle
code snippet:
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(28.7, -15.0),
mapTypeId: 'terrain'
});
map.data.loadGeoJson('http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_week.geojson');
map.data.setStyle(function(feature) {
var magnitude = feature.getProperty('mag');
return {
icon: getCircle(magnitude)
};
});
map.data.addListener('click', function(event) {
var infowindow = new google.maps.InfoWindow({
content: event.feature.getProperty('place')
});
infowindow.setPosition(event.latLng);
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, "load", initMap);
// from google sample at: https://developers.google.com/maps/documentation/javascript/earthquakes
function getCircle(magnitude) {
return {
path: google.maps.SymbolPath.CIRCLE,
fillColor: 'red',
fillOpacity: .2,
scale: Math.pow(2, magnitude) / 2,
strokeColor: 'white',
strokeWeight: .5
};
}
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>

Change Custom Marker Size Google Maps

I managed set a custom icon for the image marker (url of icon is in code), but I have no idea how to customize its size. I've looked around for help online, but due to my very limited coding knowledge, have not been able to add the code needed to make it work. Can someone send me the complete, finished code with the modification needed to customize width/height for the market icon?
Thank you!
<script src='https://maps.googleapis.com/maps/api/js?v=3.exp&key=AIzaSyDL51DzuRotMkfR09g540u2dZHlKPMpR54'></script>
<div style='overflow:hidden;height:450px;width:100%;'>
<div id='gmap_canvas' style='height:450px;width:100%;'></div>
<style>
#gmap_canvas img {
max-width:none!important;
background:none!important
}
</style>
</div>
<script type='text/javascript'>
function init_map(){
var myOptions = {
scrollwheel: false,
draggable: false,
zoom:16,
center:new google.maps.LatLng(25.841211,-80.308539),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('gmap_canvas'), myOptions);
marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(25.841211,-80.308539),
icon: 'http://www.ssglobalsupply.com/images/location-contact.png'
});
infowindow = new google.maps.InfoWindow({
content:'6891 NW 74th St Medley, FL 33166<br>'
});
google.maps.event.addListener(marker, 'click', function(){
infowindow.open(map,marker);
});
infowindow.open(map,marker);
}
google.maps.event.addDomListener(window, 'load', init_map);
google.maps.event.addDomListener(window, "resize", function() {
var center = map.getCenter();
google.maps.event.trigger(map, "resize");
map.setCenter(center);
});
</script>
The size arguments are in pixels. So, to double your example's marker size the fifth argument to the MarkerImage constructor would be:
new google.maps.Size(42,68)
Check the link for steampowered's answer to get more details
Here is the JSFIDDLE for your icon marker size 50px x 50px
var image = {
url: 'http://www.ssglobalsupply.com/images/location-contact.png',
// This marker is 50 pixels wide by 50 pixels high.
size: new google.maps.Size(50, 50),
// The origin for this image is (0, 0).
origin: new google.maps.Point(0, 0),
// The anchor for this image is the base of the flagpole at (0, 32).
anchor: new google.maps.Point(0, 32)
};

Centering Google Maps on responsive resize with marker

I'm trying to get Google Maps to keep its center when resizing responsively.
I've managed to get the map to center but can't work out how to add my marker back in to the JS to make it center too. I'm using the code from here for the map centering... Google maps responsive resize
var map; //<-- This is now available to both event listeners and the initialize() function
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(LAT,LNG),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
scrollwheel: false,
keyboardShortcuts: false,
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);}
google.maps.event.addDomListener(window, 'load', initialize);
google.maps.event.addDomListener(window, "resize", function() {
var center = map.getCenter();
google.maps.event.trigger(map, "resize");
map.setCenter(center);
});
The code I am using to center the map is above. I have the marker code below too, but I'm not sure how to add it to make it keep its center too.
var marker = new google.maps.Marker({
position: new google.maps.LatLng(LAT,LNG),
map: map,
title: 'Title',
animation: google.maps.Animation.DROP,
})
}
Can anybody help with this?
Here is a first step to get what you want to do:
var map; //<-- This is now available to both event listeners and the initialize() function
var mapCenter; // Declare a variable to store the center of the map
var centerMarker; // declare your marker
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(LAT,LNG),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
scrollwheel: false,
keyboardShortcuts: false,
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// Create a new marker and add it to the map
centerMarker = new google.maps.Marker({
position: new google.maps.LatLng(LAT,LNG),
map: map,
title: 'Title',
animation: google.maps.Animation.DROP
});
mapCenter = map.getCenter(); // Assign the center of the loaded map to the valiable
}
google.maps.event.addDomListener(window, 'load', initialize);
google.maps.event.addDomListener(window, "resize", function() {
// Here you set the center of the map based on your "mapCenter" variable
map.setCenter(mapCenter);
});
Edit: Based on #Chad Killingsworth comment:
You may want to add an 'idle' event handler to the map to set the mapCenter variable. You can achieve this like this:
google.maps.event.addListener(map,'idle',function(event) {
mapCenter = map.getCenter();
});
Description of the 'idle' event from the doc:
This event is fired when the map becomes idle after panning or zooming.

dragend event listener not firing in Google Maps API v3?

It won't even log to the console. I'm not sure what's going on here:
var mapOptions = {
zoom: 5,
center: new google.maps.LatLng(-41.2, 173.3),
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
}
var homeMarker = new google.maps.Marker();
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
google.maps.event.addListener(map, "click", function(event) {
// If the marker already exists, set it's position to null
if (homeMarker) {
homeMarker.setPosition(null);
}
// Instantiate the marker again
homeMarker = new google.maps.Marker({
position: event.latLng,
map: map,
title: 'Your Home Location',
draggable: true
});
// Set the input fields to the latitude and longitude
var latitude = event.latLng.lat();
var longitude = event.latLng.lng();
$('input#homeLat').val(latitude.toFixed(6));
$('input#homeLong').val(longitude.toFixed(6));
});
// What is wrong here?
google.maps.event.addListener(homeMarker, "dragend", function(event) {
console.log('foo');
});
Basically, what is meant to happen is that I want to fetch the coordinates from the new position of the marker, which can be changed via a click on the map and a drag of the marker itself. I've got the former working, but my eventListener for dragend doesn't seem to be firing at all. Any ideas?
Alert while dragging, same code works for me.
getPosition() helps to get the current marker position
Try this,
google.maps.event.addListener(homeMarker, "dragend", function(event) {
alert('map dragged');
homeMarker.getPosition();
});

Categories