MapQuest Developer Blog

Archives for Antony Pegg

  • Search Service Part 3 - Other cool twiddly bits

    In my last two posts I covered the basics of ways you can search, and what data you can search using our new Search Service. For this post I'm going to cover some of the cool things the service has to offer that didn't fit into my previous posts. If you haven't already, you might want to check out Search Service Part 1 - How to Search and Search Service Part 2 - What can I search? before reading this post.

    Other things the Search Service can do

    Search by Travel Time or Distance
    This is not so much a separate search, instead, something you can do on a radius search using the units= parameter. Instead of choosing miles or kilometres, you can also choose walking or driving minutes, or driving miles or kilometres. If you do this, then the results are filtered to show only those locations you could get to in that amount of time, or by traveling that distance along roads.
    ExtraCriteria
    When searching HostedData you can provide a SQL "WHERE" fragment to help further filter your results. Lets say, for example, that you've uploaded a table of restaurants that includes a field ("amex") that specifies whether the restaurant accepts American Express. When doing a search, you could use ExtraCriteria:"amex=1" to only return restaurants that take American Express.
    Specifying Field Names
    With HostedData, you can ask to only have certain fields returned, which is useful for keeping the size of the response down if you don't need all the fields. All you have to do is provide an array of the field names you do want. If you don't provide the array, we'll return all fields for each record by default.
    Results Paging
    You don't have to receive all your results at once. If you tell us a pageSize on your request, we'll break the results down into pages and store them in memory temporarily. The first response will tell you how many pages your results were broken down into, as well as a pageKey. After that, you can just ask for more results using the pageKey and currentPage parameters.
    Mixing Data Sources
    You can search multiple data sources at once and they don't even have to be the same kind of data source. If you wanted to, you could search 2 HostedData tables, some pieces of RemoteData, and the MapData all at once. Be careful though, the Max Results setting applies across all results, not per data set. If you search 5 data sets at once with a Max Results of 50, you'll get 50 total results collated from all data sets, not 50 from each.
    Get Record Info
    If you already know the record ID of the data row you need, you can use that ID with the recordInfo function to only get the records you want without having to do a spatial search. This is very useful if you want to initially provide some basic info on each search result (a more compact response than returning all fields), and then provide full details if the user drills in for more information.
    SSL Support
    Like all our services, you can access the search result over HTTPS for increased security. There's really not much to say on this one. Any URLs in the return (like the suggested display icons for the NTPois data set) will also be returned as HTTPS when using SSL.
    KML Support
    The Search Service supports outFormat=KML as an alternative return format from JSON or XML. When using our JavaScript or ActionScript SDKs, you can use a search term as the URL for a KML RemoteCollection, and watch the search results appear right on the map.
    Philadelphia parks loaded from KML using the Search Service A map of Philadelphia, using a RemoteCollection to load the parks as KML from the search service, and then display on the map
    Well, that's about all the words I have on the Search Service. Thanks for bearing with me across three rambling posts. The amount of functionality and power in the service has definitely made it interesting to blog about. More details are, as always, available on our Developer Network Beta Release page. If you haven't tried any of our new services and SDKs in Beta yet, you can sign up for an appKey here. Stay tuned...more to follow soon.
  • Search Service Part 2 - What can I search?

    In my last post I described the various ways you can search using the new Search Service. This post I am focusing on what you can search; in other words, the data that is available in the Service.

    What you can search against:

    Hosted Data
    These are data tables that MapQuest keeps on its own servers for you to search against. There are two main types of Hosted Data: those we provide (like the NAVTEQ POI tables) and those you can upload yourself through our Data Manager tool on the Developer Network.
    There are a whole bunch of tables we have up for searching against. The documentation contains a full list of the tables. Clicking on each table name will show you the table schema. Some tables are not actually for spatial searching, but contain the category names for the records in the main table. Not all tables are available for all editions, so it is a good idea to check the documentation to make sure the appKey you are using has access.
    If you don't specify any data sources to search, we'll use MQA.NTPois as the default. Everyone has access to this one and it contains over 2 million POIs across 50+ categories. The category names are in the MQA.NTPoisCat table. Use the RecordInfo function to retrieve rows from HostedData tables without doing a spatial search.
    For your own tables, you can upload whatever points you want - it's your table. Each table you create has 20 default fields, including a record ID, a name, address fields, phone numbers, and of course latitude & longitude (without which we couldn't do the searching!) Don't worry if you don't have the co-ordinates, we'll geocode anything on the way through. You can then create up to 100 additional fields for the table, calling them whatever you want.
    I'll go into more depth on the Data Manager tool in another post, but to summarize: you can create your own data tables on our server and upload your records into it. We'll geocode the records for you if you need, and then store them with a unique HostedData name that you can then search against using the Search Service. Only you have access to your table, so we check the name against your appKey, to make sure it is you using it.
    Remote Data
    If you have some of your own data that you want to search, and you don't want to host it in our databases, that's fine. You can still search it by passing it in to the search function using the RemoteData parameter. Remember that you are passing this data as part of a GET or POST, so you want to be aware of size limitations, and impact to latency and speed! Don't be surprised if you pass a massive chunk of data over the wire and things take a little longer.
    Map data
    You can also search the underlying data we use to make the maps. When you do this, you can get back points, lines or polygons that you could use, for example, to draw interactive shapes on a map. Be aware that the map data is also broken down into different data sets, so you should refer to the documentation to make sure you are searching in the country you want to search in. There's also a list on the same page of the different map features you can search for, so you can limit your search to, for example, getting the polygons of all the parks that are within 20 miles of the center of Washington D.C.
    And that's part 2 done! Next post I'll go over some of the cool miscellaneous features of the Search Service. More details are, as always, available on our Developer Network Beta Release page. If you haven't tried any of our new services and SDKs in Beta yet, you can sign up for an appKey here. Stay tuned...more to follow soon.
  • Search Service Part 1 – How to Search

    .codeblock { -moz-background-clip:border; -moz-background-inline-policy:continuous; -moz-background-origin:padding; background:#F5F4EE none repeat scroll 0 0; border:2px dotted #DDDDDD; color:#06263C; font-family:courier,monospace; width:100%; } .picture { background-color: #F9F9F9; border: 1px solid #CCCCCC; padding: 3px; font: 11px/1.4em Arial, sans-serif; } .picture img { border: 1px solid #CCCCCC; vertical-align:middle; margin-bottom: 3px; } .right { margin: 0.5em 0pt 0.5em 0.8em; float:right; } .left { margin: 0.5em 0.8em 0.5em 0; float:left; }

    Before Christmas we pushed the new Search Service out to Beta and then expanded its features in subsequent pushes. At this point, it's pretty much fully baked, and more than complete enough to deserve some blogging. It's taken me a while to pull this post together, mainly because every time I tried to write about the new search service, I was defeated by the amount of functionality, options, and flexibility it possesses. It's not a simple "gimme Pizza in Denver" search (although it can be) - it's a lot more hardcore than that. It's a Spatial Search Service, which allows you to search against different data sets by defining the geographic area within which you want results found.

    While the service is easy to implement, it is highly functional and has many capabilities, so please bear with me as I try to explain just some of the things it can do. To make it simple I'm going to break this down into three separate posts: Ways you can search (this post); what data you can search against; and miscellaneous cool stuff it can do.

    Ways you can search:


    Radius Search
    This is the most basic search. Give us a point and how far around it you want to search, and we'll return results ordered by their distance from the center. You can tell us the center-point of your search by providing a latitude/longitude, a street address, or an IP address. In fact, if you don't give us a center-point, we'll default to your IP address. See how easy that was? From here, you simply tell us the radius and the units. 10 kilometres? No problem! Half-an-hour driving time? Yes, we can do that too!
    Radius Search
    Radius search results on a map.
    Rectangle Search
    If you give us two points (again, Lat/Lngs, street addresses, IP addresses, or any combination of the three), we'll make a rectangle out of them and search within that box. This is a great way to do a map-based search; Just pass the map bounds every time your user pans or zooms the map, and re-query for updated search results.
    Rectangle Search
    Rectangle search results on a map.
    Polygon Search
    Sometimes you need more than just a radius or a bounding box. A lot of companies have custom defined sales territories; or maybe you sell franchise with Areas of Protection, and need to make sure a new franchise territory wouldn't include any previously sold franchises. You can define the polygon by handing us a collection of lat/lng pairs in several different formats: a raw comma-separated set of of pairs, an encoded compressed string, or an OGC standard Simple Feature.
    Polygon Search
    Polygon search results on a map.
    Corridor Search
    The most obvious use of Corridor Search is to find places along a route (such as gas stations or hotels). You provide the line shape and how wide you want the line to be and we supply the results. For example, if you set a width of "5" and a units of "k" (kilometres) then we'll search for 2.5 km on each side of the line (a total width of 5 km). Corridor Search supports the same line input types as the polygon search does. If you have previously created a route using the Directions Service you can also use the sessionID from that route, instead of providing us the line shape.
    Corridor Search
    Corridor search results on a map.
    Base or Default Search
    Finally, there is just a base search? function that sits on top of all the others. Pass us the parameters of your search, and we'll figure out what kind of search you are trying to do. Give us a point and a radius, we'll do a radius search; Give us two points, we'll do a rectangle; Give us a series of points, we'll do a corridor. If the first and last points are the same, then we'll do a polygon search instead. In fact, if you give us absolutely nothing at all, we'll do a 20 mile radius search around your IP address against our default data-set.

    And that's just part 1! Hopefully you can see how these new capabilities can help you. More details are, as always, available on our Developer Network Beta Release page.

    If you haven't tried any of our new services and SDKs in Beta yet, you can sign up for an appKey here.

    Stay tuned...more to follow soon.

  • Traffic Service released to Beta

    .codeblock { -moz-background-clip:border; -moz-background-inline-policy:continuous; -moz-background-origin:padding; background:#F5F4EE none repeat scroll 0 0; border:2px dotted #DDDDDD; color:#06263C; font-family:courier,monospace; width:100%; } .picture { background-color: #F9F9F9; border: 1px solid #CCCCCC; padding: 3px; font: 11px/1.4em Arial, sans-serif; } .picture img { border: 1px solid #CCCCCC; vertical-align:middle; margin-bottom: 3px; } .right { margin: 0.5em 0pt 0.5em 0.8em; float:right; } .left { margin: 0.5em 0.8em 0.5em 0; float:left; }

    Now that we've completed and released the new Geocoding service, Directions Service, and Static Map Service, we're moving on to the next round of web services. The first one up to the plate is the new Traffic Service.

    This is actually the second Beta release, and we have three functions completed now: One to get a list of markets, one to get a list of the current traffic incidents in a given area, and a third to get a raster image of the traffic flow conditions to overlay on a map.

    The first function, /traffic/v1/markets?, is a simple call to get a list of the markets for which we have traffic. There are no parameters (except your appkey). It simply returns a list of market names, a Center Latitude/Longitude, an icon to use, and a suggested bounding box for zooming in. We use this function to show the traffic markets on zoomed-out maps, and create the "zoom to market" links in the market infoWindows.

    Main Markets
    Showing the Markets feed on a map.

    The second function,/traffic/v1/incidents?, lets you request all incidents within a given bounding box. You can filter on which incident types you want returned ("Construction" for example). Each incident provides type and location details, an appropriate icon to use, a short and full description, and timing/duration info.

    Incidents in a market
    Showing the incidents on a map.

    The third function,/traffic/v1/flow?, returns a transparent raster image of color-coded traffic flow for a given MapState. A MapState is a core object of our mapping SDKs that contains the map center-point, the zoom level, and the height/width of the map.

    Incidents in a market
    Showing both incidents and flow on a map.

    The service is all part of the new platform we've been building out, so it comes with the ability to GET with Key-value pairs, or GET or POST with JSON or XML, and receive your response in a different format to your request (eg: send in XML, get it returned as JSON).

    Obviously we're not done yet. An important thing for us here is to make sure the exposed service is consistent with the other services we've recently released (the geocoding, directions, and static map). So - please, please let us know if you find any inconsistencies in the object / node names in the request / return, compared to the others.

    More details are, as always, available on our Developer Network Beta Release page.

    If you haven't tried any of our new services and SDKs in Beta yet, you can sign up for an appKey here.

    Stay tuned...more to follow soon.

  • Alternate Routes added to Directions Service Beta

    .codeblock { -moz-background-clip:border; -moz-background-inline-policy:continuous; -moz-background-origin:padding; background:#F5F4EE none repeat scroll 0 0; border:2px dotted #DDDDDD; color:#06263C; font-family:courier,monospace; width:100%; } .picture { background-color: #F9F9F9; border: 1px solid #CCCCCC; padding: 3px; font: 11px/1.4em Arial, sans-serif; } .picture img { border: 1px solid #CCCCCC; vertical-align:middle; margin-bottom: 3px; } .right { margin: 0.5em 0pt 0.5em 0.8em; float:right; } .left { margin: 0.5em 0.8em 0.5em 0; float:left; }

    If you ask three people for directions to somewhere they journey to frequently, you are likely to receive three different sets of directions. Each person will have some short-cut, or uses one road over another because of traffic, or has a particular highway they always want to avoid. Personally, I'll drive extra miles down unnecessary roads just to avoid traffic lights. I know its an illusion, but even if the trip ultimately takes longer than sitting at traffic lights along a shorter road, I'd rather keep moving.

    In order to emulate the experience of having multiple friends bicker about which is the best route you should take, our Directions team have created ....(wait for it)... Alternate Routes! (Dun Dun DUUUN!) Joking aside, I think this is very very cool functionality. The function call is basically the same as a regular route call, with a couple of extra parameters:, and looks like this:


    The maxRoutes parameter is how many total possible routes you want back, including the first (or "main") one. The Overage is a percentage extra time thats allowable for an alternate route to take. For example, on an hour-long route, an overage of 25 is 25% would be up to an extra 15 minutes.

    So lets say you set a maxRoutes=3. The response will include the "main" route, just like normal, plus an additional node containing up to two other routes that provide alternative ways to your destination. Each route will also have a new "name" node to help identify them. We try to fill this with the name of a road that is unique to that particular route. Each route is complete with narrative, road shields and thumbnail maneuver maps.

    Here is an example of travelling from Harrisburg to Reading in pennsylvania, asking for a total of three routes (2 alternate routes):

    Main Route
    The Main Route, which we named "Interstate 76 E", takes you down to the Pennsylvania Turnpike. It is calculated to take 1 hour 7 minutes to travel just under 59 miles.
    Alternate Route #1
    The first Alternate Route avoids the Turnpike, and instead takes you up Interstate 81 and along Interstate 78. It takes a few more minutes overall, but avoids a big toll road. It is calculated to take 1 hour 12 minutes to travel around 63 miles.
    Alternate route #2
    The second Alternate Route takes you in a very direct route along Routes 322 and 222. It is shorter than the other routes, but takes a little longer than both of them, clicking in at 1 hour 21 minutes, to travel under 55 miles.

    So thats how it works!. Pretty darn cool, eh? More details, Documentation and sample links are found (as always) on the Developer Network beta page. The sample I took the screenshots from is part of the service documentation

    Let us know on the Beta Forums if you find any issues, or if you create a cool application using Alternate Routes.