tags:

views:

3443

answers:

6

Hi all,

I'm having some trouble with the Google Maps API; I want to determine a LatLong for a certain place (for example, from the name of a city), then focus my map on it. The LatLong part is working, and so is centering the map on that point. However, I cannot figure out how to determine what a good zoomlevel might be when I only have that single point. I cannot just go to some standard zoomlevel that might look good most of the time, 'cause what happens when the user enters "Russia" instead of "Amsterdam", for example? Some help would be appreciated :)

+1  A: 

Your question is missing a input parameter . You are saying LatLon point but actually you need LatLonBounds to do the focusing for available map window size . I assume you want to mimic the official Google map behavior. Besides geocoding they rely on other data which Gmap API doesnt have access to. So you have to provide your own.

BigInJapan
A: 

The following call will give you the zoom level if you can provide it with an appropriate rectangular bounds object:

GMap2.getBoundsZoomLevel(bounds)

But how to calculate the bounds?

You can manually annotate each source record with a rectangle determined "by eye" using a map and have someone type in values.

Ideally you want data, and luckily there is shed loads of data on DBPedia.

My geometry and algebra is a little rusty, but with a little of both I'm sure you can calculate a rectangle given the area of the location you want to view. (Maybe start with the square root if assuming a square city, or rearrange πr2 if assuming a circular one)

Try out this query to extract the areas of regions.

PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#&gt;
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX dbpedia2: <http://dbpedia.org/property/&gt;
SELECT ?url, ?label, ?lat, ?long, ?area WHERE {
   ?url geo:lat ?lat .
   ?url geo:lat ?long .
   ?url rdfs:label ?label . FILTER ( lang(?label) = 'en' ) .
   ?url dbpedia2:area ?area . FILTER ( datatype(?area) = xsd:double ) 
} LIMIT 10

You'll need to cache the results or load them into a faster more local datasource as DBPedia is searching millions of triples of unstructured data (well RDF data). You can download the Titles, Infobox and coordinates data sets from DBPedia and load them into e.g. Jena. Remember to turn off all the validation options during loading :-)

You can also access this data using a RESTful API which has fairly usable Web form, and its possible to pull the URL its generating using "Copy download link button" in the firefox downloads window, or setting the output format to HTML. It also generates XML and JSON.

Don't forget to add a margin for wobbly shaped cities...

Simon Gibbs
+2  A: 

I just asked this question at Google IO. This feature exists, but is undocumented and doesn't have accessors for it yet. What you want to do is get the Structured Address. Inspect the json structure you get back and look for these new parameters. I'll post more information when I get a chance to try this out.

Nick Retallack
A: 

Are you getting your location points from the Geocoder? If you are, you can grab the accuracy of the point and base your zoom on that (higher accuracy = higher zoom).

Chris B
+1  A: 

I had the same question, and Nick Retallack's response, is what worked for me. To provide more detail, the name of the undocumented property is "ExtendedData", and within that you have "LatLonBox" which contains the north, south, east and west boundaries of the appropriate zoom level.

For instance, if you were to do a search for "90210", here's the output (which I've formatted for readability):

{
    "id":"p1",
    "address":"Beverly Hills, CA 90210, USA",
    "AddressDetails":{
        "Accuracy":5,
        "Country":{
            "AdministrativeArea":{
                "AdministrativeAreaName":"CA",
                "SubAdministrativeArea":{
                    "Locality":{
                        "LocalityName":"Beverly Hills",
                        "PostalCode":{"PostalCodeNumber":"90210"}
                    },
                    "SubAdministrativeAreaName":"Los Angeles"
                }
            },
            "CountryName":"USA",
            "CountryNameCode":"US"
        }
    },
     // This is what you're looking for
     "ExtendedData":{
         "LatLonBox":{
             "north":34.13919,
             "south":34.067018, 
             "east":-118.38971, 
             "west":-118.442796
         }
     },
    "Point":{
        "coordinates":[-118.4104684,34.1030032,0]
    }
}

This is undocumented though, so I'm not sure if it'll survive API changes. Best not assume it'll always be there, and define some reasonable default zoom value.

Jack Leow