I am developing a Web Based Application using PHP, MongoDB, Javascript, and Google Maps API V3.
I was able to easily generate and display markers on a google map by converting the MongoDB array using json_encode. Here's an example map with markers and infowindow.
Markers and InfoWindow
However, when I try to implement the Google Maps MarkerClusterer method, the markers disappears. I followed Google Map's "A Simple MarkerClusterer Example" as a guide.
I also tried declaring a global cluster object, passing it an empty array,
var markerCluster = new MarkerClustrer(map, markers);
then using markerCluster.addMarkers(markers, true); as alternate method with no luck.
It seems pretty simple but somehow, it is not displaying the markers. I also tried commenting out the whole infoWindow/OnClick event section so I don't think its related to that. Any help is greatly appreciated.
PHP MongoDB Query:
<?php
// Connect to Mongo and set DB and Collection
try
{
$mongo = new Mongo();
$db = $mongo->selectDB('twitter');
$collection = $db->selectCollection('tweets');
}
catch(MongoConnectionException $e)
{
die("Failed to connect to Twitter Database ". $e->getMessage());
}
// The hotspots array will contain the data that will be returned
$tweets = array();
// Return a cursor of tweets from MongoDB
$cursor = $collection->find();
// Try catch for catching whether there are tweets to display
$count = 0;
try
{
$count = $cursor->count();
}
catch (MongoCursorException $e)
{
die(json_encode(array('error'=>'error message:' .$e->getMessage())));
}
// Loops through the cursor again specifically for querying all geo locations
// Unlike table display of tweets, this cursor is not limited by pages.
foreach($cursor as $id => $value)
{
$mapLocations[] = array
(
'id'=>$value['_id'],
'screen_name'=>$value['screen_name'],
'name'=>$value['name'],
'tweet'=>$value['tweet'],
'hashtags'=>$value['hashtags'],
'lat'=>$value['geo']['lat'],
'long'=>$value['geo']['long'],
'date'=>$value['date'],
'img'=>$value['img'],
'specImg'=>$value['specImg']
);
}
// var_dump($mapLocations);
?>
Javascript Function:
function initialize()
{
// Converts MongoDB information to JSON, ready for Javascript
var tweets = <?php echo json_encode($mapLocations); ?>;
// Sets google maps options
var myOptions =
{
// Centers on Maui...
center: new google.maps.LatLng(20.80362, -156.321716),
zoom: 7,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
// Sets Marker Clusterer Options
var mcOptions =
{
gridSize: 50, maxZoom: 15
};
// Generates Google Map and applies the defined options above.
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Infowindow for displaying information for onClick event
// Content must be inside the google.maps.event function
// Otherwise the same content will be entered on all markers
var infoWindow = new google.maps.InfoWindow({});
var markerCluster = null; // Initializes markerCluster
var markers = []; //Array needed to pass to MarkerClusterer
// Loops through each tweet and draws the marker on the map.
for (var i = 0; i < tweets.length; i++)
{
var tweet = tweets[i];
if(tweet.lat != null || tweet.long != null)
{
var myLatLng = new google.maps.LatLng(tweet.lat, tweet.long);
//document.write(" Latitude: " + tweet.lat + " Longitude: " + tweet.long + " <br> ");
var marker = new google.maps.Marker({
position: myLatLng,
//icon: "markers/flag.png",
//map: map,
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i)
{
return function()
{
// Generates a table for infoWindow
var content = "<table class='popup'>";
// Check if image exits, otherwise show no image icon
if(tweets[i].specImg != null)
{
content += "<tr><th width=75 ><a href=" + tweets[i].specImg + ">";
content += "<img height=75 width=75 src=" + tweets[i].specImg + "></a>";
}
else
{
content += "<tr><th width=75><img height=75 width=75 src=images/noimage.jpg>";
}
// Concatanate screen name and tweet
// Will work on trimming information
content += "</th><td>" + tweets[i].screen_name + " says...<br>";
content += "''" + tweets[i].tweet + "''<br>";
content += "on " + tweets[i].date + "</td>";
content += "</table>";
// Zoom into marker on click
map.setZoom(15);
map.setCenter(marker.getPosition());
// Sets the infoWindow content to the marker
infoWindow.setContent(content);
infoWindow.open(map, marker);
}
})(marker, i));
}
}
var markerCluster = new MarkerClusterer(map, markers);
}
#Robbie:
The JSONned $mapLocations becomes a multidimensional array but I simplified the $mapLocations to only store a 2D lat and long. The javascript source code becomes as follow.
var tweets = [{"lat":20.87179594,"long":-156.47718775},{"lat":20.87195633,"long":-156.47714356},{"lat":20.87138419,"long":-156.47719744},{"lat":21.3320704,"long":-157.8685716},{"lat":null,"long":null},{"lat":21.36509415,"long":-157.92824454},{"lat":21.3320825,"long":-157.8684742},{"lat":null,"long":null},{"lat":21.33673131,"long":-157.86824},{"lat":21.332507,"long":-157.86635342},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":37.36520709,"long":-121.92386941},{"lat":37.2499758,"long":-121.86462506},{"lat":37.36278955,"long":-121.90521146},{"lat":null,"long":null},{"lat":37.36278955,"long":-121.90521146},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":20.88944108,"long":-156.4761887},{"lat":37.36273157,"long":-121.90479984},{"lat":20.85102618,"long":-156.65936351},{"lat":20.88949978,"long":-156.4762491},{"lat":null,"long":null},{"lat":21.3320168,"long":-157.8685715},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null}];
FINALLY FIGURED IT OUT:
As I expected, it was something very simple.
Apparently you need to download the markerclusterer.js file from the Google Maps Utility Library. I thought the clusterer was already built in into the API itself.
I fixed it by downloading the script into server and referencing it like so
<script type="text/javascript" src="markerclusterer.js"></script>
Anyways, thanks everyone for the help!
I think there may be a couple of issues:
The infowindow is required per marker, you are sharing one infowindow for all the markers and repeatedly changing its contents.
Also check that you don't fall into the closure trap. I could retpye it all, but you basically need to create a function out of the closure. There is an explination of how to do this at http://www.robertbolton.com/blog/google-maps-v3-multiple-markers-and-infowindows-in-a-loop
Related
I am trying to make a database of locations to fill out a FAFSA for my non profit and put them up on a google map with a custom marker image but cant seem to get the markers to show up.
here is the php to create the xml:
<?php
require("mapdbinfo.php");
// Start XML file, create parent node
$dom = new DOMDocument("1.0");
$node = $dom->createElement("markers");
$parnode = $dom->appendChild($node);
// Opens a connection to a mySQL server
$connection=mysql_connect ("Localhost", $username, $password);
if (!$connection) { die("Not connected : " . mysql_error());}
// Set the active mySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) { die("Can\'t use db : " . mysql_error());}
$query = "SELECT * FROM locations WHERE 1";
$result = mysql_query($query);
if (!$result) { die("Invalid query: " . mysql_error());}
header("Content-type: text/xml");
// Iterate through the rows, adding XML nodes for each
while ($row = mysql_fetch_assoc($result)){
// Add to XML document node
$node = $dom->createElement("marker");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("name",$row['name']);
$newnode->setAttribute("address", $row['address']);
$newnode->setAttribute("lat", $row['lat']);
$newnode->setAttribute("lng", $row['lng']);
$newnode->setAttribute("type", $row['type']);
$newnode->setAttribute("date", $row['date']);
$newnode->setAttribute("cord", $row['cord']);
$newnode->setAttribute("cord_info", $row['cord_info']);
}
echo $dom->saveXML();
?>
here is the java script:
function load() {
var location_icon = new google.maps.MarkerImage('images/FAFSA_Logo_icon.png');
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(35.105305, -106.628014),
zoom: 9,
mapTypeId: 'roadmap'
});
var infoWindow = new google.maps.InfoWindow;
}
downloadUrl("mapmysql.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address + "<b> Cordinator </b>" + cord + cord_info;
var icon = location_icon;
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
function downloadUrl(url,callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
I can't figure out why they markers aren't showing up. the file is located in that images folder but, there are to many places that this could be going wrong for me to effectively troubleshoot with my current knowledge. I pretty much copied and pasted the code from the google example except for adding some fields to pull from the xml and added a custom icon image.
Any ideas on how to get these markers to show up? the map shows up with the center and zoom I have selected but not the markers.
I think I may see a few problems (I'll get to them in a minute), but first I'm going to try to offer some more general debugging advice -
Testing someone's code which relies on a server-side code is pretty tricky, even if it's your own. The first thing I would do in a case like this is create a generic xml file to parse, and include it in the page. Then, hopefully you can tell if the bug is occurring in the map rendering portion of the code if something goes wrong. If it works, then you can narrow the bug down to being either on the server, or in the code you're using to get it from the server.
Next, I would try to put the xml file on the server as-is, and see if the client-side file download is working. I suspect this is where you'd notice at least one error. Right now, your map rendering depends on two separate steps: the "load" function, which initializes the map; and a call to the "downloadURL" function, which you're relying on to get the marker data.
The problem is in how you structured the calls. The "map" variable you created in "load" is local to "load" itself; you cannot access it outside of it. There are two ways you can fix this particular problem: you can turn map into a global variable, or add all code that manipulates map within "load". If you wish to do the former, you just do this:
var map;
function load() {
var location_icon = new google.maps.MarkerImage('images/FAFSA_Logo_icon.png');
map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(35.105305, -106.628014),
zoom: 9,
mapTypeId: 'roadmap'
});
var infoWindow = new google.maps.InfoWindow;
}
This adds "map" to the global scope, allowing it to be used outside of "load".
However, there's still a problem with doing this as-is: this won't guarantee that "load" has initialized the map by the time "downloadURL" starts manipulating it. There's a chance that it will attempt to add "markers" to "map" before "load" has had a chance to create map in the first place. Fortunately, this can be solved by putting the "downloadURL" call within "load", like so:
function load() {
var location_icon = new google.maps.MarkerImage('images/FAFSA_Logo_icon.png');
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(35.105305, -106.628014),
zoom: 9,
mapTypeId: 'roadmap'
});
var infoWindow = new google.maps.InfoWindow;
downloadUrl("mapmysql.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for(var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address + "<b> Cordinator </b>" + cord + cord_info;
var icon = location_icon;
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
}
This ensures that markers will only be added to the map after the map has been created, and that they'll have access to map in the first place.
Check the javascript console for errors
Check the xml. Point your browser at it, see if it thinks it is valid.
Use a debugger (or just add an alert) in your map where it parses the marker xml, check that the length of the markers variable that is being processed by this for loop is correct:
for (var i = 0; i < markers.length; i++) {
One of the above should point to the issue. If not, post a link to your live map and someone can figure it out.
I'm developing a web page with a Google Maps API v3. I currently have a functional map and search bar. I need to be able to display the distance from a searched address to the nearest placemark on one of the KML files on the map. How can I do this?
Here is the code for the page:
<script type="text/javascript">
var geocoder;
var map;
var marker;
var layers = [];
function initialize() {
geocoder = new google.maps.Geocoder ();
var latlng = new google.maps.LatLng (41, -73.4);
var myOptions = {
zoom: 7,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
marker = new google.maps.Marker({map:map});
layers[0] = new google.maps.KmlLayer('http://dl.dropbox.com/u/80233620/South-and-North-County-Trailway.kml',
{preserveViewport: true});
layers[1] = new google.maps.KmlLayer('http://www.nyc.gov/html/dot/downloads/misc/cityracks.kml',
{preserveViewport: true});
layers[2] = new google.maps.KmlLayer('http://dl.dropbox.com/u/80233620/NWS%20Radar%20Images.kmz',
{preserveViewport: true});
for (var i = 0; i < layers.length; i++) {
layers[i].setMap(map);
}
}
function codeAddress () {
var address = document.getElementById ("address").value;
geocoder.geocode ( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results [0].geometry.location);
marker.setPosition(results [0].geometry.location);
map.setZoom(14);
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function toggleLayer(i) {
if(layers[i].getMap() === null) {
layers[i].setMap(map);
}
else {
layers[i].setMap(null);}
}
</script>
You cannot access the data in KML layers like that
https://developers.google.com/maps/documentation/javascript/layers#KMLLayers
Because KML may include a large number of features, you may not access
feature data from the KmlLayer object directly. Instead, as features
are displayed, they are rendered to look like clickable Maps API
overlays.
Instead you can process the XML and add markers manually, then use the geometry library and computeDistanceBetween() to get the distance. I usually multiply the distance by some number to account for turns (The distance formula gets a straight line distance). I believe around 1.2 was the most accurate.
I want to know how to make some sort of event in javascript that will be triggered ever time when new data is inserted?
I need this so I can use live tracking in google maps.
For example this is the code that I have found on geolocation page:
function scrollMap(position)
{
// Scrolls the map so that it is centered at (position.coords.latitude,position.coords.longitude).
}
// Request repeated updates.
var watchId = navigator.geolocation.watchPosition(scrollMap);
function buttonClickHandler()
{
// Cancel the updates when the user clicks a button.
//I want to put my code in here so for example when I click button live tracking starts.
navigator.geolocation.clearWatch(watchId);
}
This is my code that I am using to retrieve array of the data:
function initialize() {
var myLatLng = new google.maps.LatLng(0, 180);
var myOptions = {
zoom: 3,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
var flightPlanCoordinates = [<?php echo implode(',', $coordinates) ?>];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
}
How can I make my code to work and get one last result every time it is inserted in the database? And show it on the map in the google code that is provided at the begining of my question.
Database is mysql it has ID,Latitude and Longitude.
EDIT:
This is my PHP code that fetches all data from database and put them in the array for google maps:
$coordinates = array();
$result = dbMySql::Exec('SELECT Latitude,Longitude FROM data');
while ($row = mysqli_fetch_assoc($result))
$coordinates[] = 'new google.maps.LatLng(' . $row['Latitude'] . ', ' . $row['Longitude'] . ')';
The simplest solution is to poll your server. Ask for entries created within the last X minutes and add the new entries.
I'm connecting a Google Map to a MySQL database to list distributors all over the world, and I seem to be having a few issues.
Sometimes the page itself will not load at all in Firefox (v4 on Mac). It's temperamental on my machine (FF v3.6 Mac) and a Windows machine (FF v4 Win 7), ok in Safari/Opera, doesn't load at all in IE 9 (Win 7). Not sure if it's a network issue or code.
Load time is pretty slow. Might be because the map covers the whole page (will create a square block to place it in).
The URL of the page is here and I used the code from Sean Feeney's page.
The code I have is:
<script src="http://maps.google.com/maps?file=api&v=2&key=<I entered my key here>" type="text/javascript"></script>
<body onUnload="GUnload()">
<div id="map" style="position:absolute;top:0px;bottom:0px;left:0;right:0;"></div>
</body>
<script type="text/javascript">
//<![CDATA[
var map;
var latlngbounds;
if (GBrowserIsCompatible()) {
function createMarker(point, address) {
var marker = new GMarker(point);
var html = address;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
function extendBounding(point) {
latlngbounds.extend(point);
var zoom = map.getBoundsZoomLevel(latlngbounds);
if (zoom < 10) {
zoom = 12;
}
map.setCenter(latlngbounds.getCenter(), zoom);
}
}
map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl3D());
map.addControl(new GMapTypeControl());
latlngbounds = new GLatLngBounds();
GDownloadUrl("genxml.php", function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var address = markers[i].getAttribute("address");
var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = createMarker(point, address);
map.addOverlay(marker);
extendBounding(point);
}
});
}
//]]>
</script>
The code that gets the data is the same as the example.
Any ideas as to why it doesn't always load in the browsers, and why it seems to take a while to load?
Thanks,
Adrian
Ideally you should wrap the code that loads the map inside a document ready or window load event.
I notice that your code is not nested properly inside the GBrowserIsCompatible() block so please fix that.
As far as I remember, Google maps API v2 requires you to call the setCenter() method before doing any operations on the map. So to begin with, set the center to (0, 0) immediately after creating the map.
I notice that you're downloading XML data before you add markers to the map. You must take into account the time taken by the server to serve the XML data. If you've called the setCenter() before downloading the XML, the map will display while the XML downloads asynchronously.
Inside the code that handles the XML data: when you add a marker, do not call setCenter() immediately. Doing so will cause the function to be called 1000 times if you have 1000 markers in your XML. Instead, just call latlngbounds.extend(point). Once you have iterated the loop, calculate the zoom/center and call setCenter(). This way you will end up calling this function only twice.
Edit
I've figured out what the problem is. The genxml.php randomly returns the string Google Geo error 620 occurred which cannot be parsed as XML which raises JavaScript errors and no markers are shown. Better have a look at the code of that file and see why this happens randomly. On other times when that file actually returns valid XML, the markers appear as expected.
It appears Google recently tightened geocoding requests. If you send 10 too fast, it cuts you off with 620 error. The solution they recommend is adding a dynamic timer. Other stackoverflow posts suggested a 0.25 second static timer was good enough, but I've found Google's recommendation of using a while loop that increments the timer value as needed works better. For example:
// Initialize delay in geocode speed
public $delay = 0;
public function lookup(arguments)
{
$geocode_pending = true;
while ($geocode_pending) {
$search = //address string to search;
$response = $this->performRequest($search, 'xml');
$xml = new SimpleXMLElement($response);
$status = (int) $xml->Response->Status->code;
switch ($status) {
case self::G_GEO_SUCCESS:
require_once('placemark.php');
$placemarks = array();
foreach ($xml->Response->Placemark as $placemark)
$placemarks[] = Placemark::FromSimpleXml($placemark);
$geocode_pending = false;
return $placemarks;
case self::G_GEO_TOO_MANY_QUERIES:
$delay += 100000;
case self::G_GEO_UNKNOWN_ADDRESS:
case self::G_GEO_UNAVAILABLE_ADDRESS:
return array();
default:
throw new Exception(sprintf('Google Geo error %d occurred', $status));
}
usleep($delay);
}
}
You can run your map code with window.load after everything is loaded:
jQuery(document).ready(function initAutocomplete() {
var p_lag=$('#longitude').val();
var p_lat=$('#latitude').val();
if(p_lat==''){
var p_lat=20.593684;
}
if(p_lag==''){
var p_lag=78.96288000000004 ;
}
var myLatLng = {lat: p_lat,lng: p_lag};
var map = new google.maps.Map(document.getElementById('dvMap'), {
center: myLatLng,
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new google.maps.Marker({
position: myLatLng,
draggable: true,
map: map,
title: 'Map'
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
//map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function () {
searchBox.setBounds(map.getBounds());
});
//Click event for getting lat lng
google.maps.event.addListener(map, 'click', function (e) {
$('input#latitude').val(e.latLng.lat());
$('input#longitude').val(e.latLng.lng());
});
google.maps.event.addListener(marker, 'dragend', function (e) {
$('input#latitude').val(e.latLng.lat());
$('input#longitude').val(e.latLng.lng());
});
var markers = [];
// [START region_getplaces]
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function () {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
/*markers.forEach(function (marker) {
marker.setMap(null);
});*/
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function (place) {
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
$('#latitude').val(place.geometry.location.lat());
$('#longitude').val(place.geometry.location.lng());
marker.setPosition(place.geometry.location);
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
});
});
}
);
GOOGLE MAPS API V3 is what i'm trying to use.
I have all the coordinates in mysql. I just, for example, need to take 5 listings and put them on a map but I'd like to be able to find the center point based on the multiple coordinates I'd like to display, and the zoom level as well. Yeah know?
I'm having the time of my life with something that I know is terribly simple, I just can't figure this API out. I'll paypal $20 to anyone who can help me.
//select * from mysql limit 5
//ok great we got 5 results, great job, format the 5 results so google maps like it, [name,lat,lng] whatever.
//put them on the map and let them be clickable so i can put stuff in the infowindow thing
//make the map adjust to the proper zoom level and center point
UPDATE
This is what i was looking for, hope this helps others.
credit to [Chris B] for the common sense math formula for getting the center coord, the sw cord is the lowest lat and lon, and the ne coord is the greatest lat and lon
sort($lat)&&sort($lon);
$r['c'] = array_sum($lat)/count($lat).', '.array_sum($lon)/count($lon);
$r['ne'] = $lat[count($lat)-1].', '.$lon[count($lon)-1];
$r['sw'] = $lat[0].', '.$lon[0];
var myOptions = {zoom:4,center: new google.maps.LatLng(<?php echo $r['c']; ?>),mapTypeId:google.maps.MapTypeId.ROADMAP}
var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
<?php foreach($x as $l) echo 'new google.maps.Marker({position:new google.maps.LatLng('.$l['lat'].','.$l['lon'].'),map:map,clickable:true});'; ?>
map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(<?php echo $r['sw']; ?>),new google.maps.LatLng(<?php echo $r['ne']; ?>)));
If an average/weighted center point is acceptable - you could just average all the latitudes, and average all the longitudes:
$latTotal = 0;
$lngTotal = 0;
foreach ($markers as $marker) {
$latTotal += $marker['lat'];
$lngTotal += $marker['lng'];
}
$centerLat = $latTotal/count($markers);
$centerLng = $lngTotal/count($markers);
For the rest of it, there are some good V3 tutorials on Google.
I was using Google Maps v3 a month or two back, but switched to v2 later on. However, I had the same problem as you so I wrote a MarkerManager class for API v3. I can't find the latest version of my class, but I did find a, hopefully, working one. You can get it here.
I have to warn you though - it's not optimazed at all and is not using overlays, so when I tried putting 50+ markers in the manager and toggled the hide/show the class is sloooow... But maybe you can have some success with it.
Usage example:
var map = new google.maps.Map(document.getElementById('MapLayerId'), {
zoom: 7,
position: new google.maps.LatLng(latitude, longitude),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker1 = new google.maps.Marker({
position: new google.maps.LatLng(latitude, longitude),
map: map
});
var marker2 = new google.maps.Marker({
position: new google.maps.LatLng(latitude, longitude),
map: map
});
var manager = new MarkerManager(map, {fitBounds: true});
manager.add(marker1);
manager.add(marker2);
manager.show();
GDownloadUrl in V2 equivalent downloadUrl in GOOGLE MAPS API V3
How to load all the coordinates in database(Mysql or Sql).
var myLatlng = new google.maps.LatLng("37.427770" ,"-122.144841");
var myOptions = {zoom: 15, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP,}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var url='marker.php?arg1=x&arg2=y...';
downloadUrl(url, function(data) {
var markers = data.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var marker = new google.maps.Marker({position: latlng, map: map});
}
});
function createXmlHttpRequest() {
try {
if (typeof ActiveXObject != 'undefined') {
return new ActiveXObject('Microsoft.XMLHTTP');
} else if (window["XMLHttpRequest"]) {
return new XMLHttpRequest();
}
} catch (e) {
changeStatus(e);
}
return null;
};
function downloadUrl(url, callback) {
var status = -1;
var request = createXmlHttpRequest();
if (!request) {
return false;
}
request.open('GET', url);
request.onreadystatechange = function() {
if (request.readyState == 4) {
try {
status = request.status;
} catch (e) {
// Usually indicates request timed out in FF.
}
if (status == 200) {
var s=request.responseText;
callback( xmlParse(s) );
}
}
}
try {
request.send(null);
}catch (e) {
changeStatus(e);
}
};
function xmlParse(str) {
if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
}
if (typeof DOMParser != 'undefined') {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
return createElement('div', null);
}
Have you checked out the official google map PHP/Mysql tutorial?
http://code.google.com/apis/maps/articles/phpsqlajax.html
Try this algorithm for finding the centroid of a polygon:
http://tog.acm.org/resources/GraphicsGems/gemsiv/centroid.c