Geospatial search, frequently referred to as geocoding, is the process of matching an address to its corresponding geographic coordinates. There's nothing inherent in the words we use to describe an address that conveys its location at some coordinates on earth, i.e. *[lat,lon]*. Making the leap from text to coordinates is an intricate and challenging process. Lucky for you, we've done all the hard work and made it accessible though a free web service.
The Mapzen Search request takes the form of `https://search.mapzen.com/v1/search?api_key={your-api-key}`, where the JSON inputs inside the `{}` include search parameters such as the text to find and filtering options. Note that you must append your own Mapzen Search API key to the URL, following &api_key= at the end.
In the simplest search, you can provide only one parameter, the text you want to match in any part of the location details. To accomplish this, build a query where the `text` is set to the item you want to find.
For example, if you want to find a [YMCA](https://en.wikipedia.org/wiki/YMCA) facility, here's what you'd need to append to the base URL of the service, `search.mapzen.com`.
Note that the results are spread out throughout the world because you have not given your current location or provided any other geographic context in which to search.
If you are looking for places in a particular region, or country, or only want to look in the immediate vicinity of a user with a known location, you can narrow your search to an area. There are different ways of including a region in your query. Mapzen Search currently supports three types: country, rectangle, and country.
Sometimes your work might require that all the search results be from a particular country. To do this, you can set the `boundary.country` parameter value to the alpha-2 or alpha-3 [ISO-3166 country code](https://en.wikipedia.org/wiki/ISO_3166-1).
Now, you want to search for YMCA again, but this time only in Great Britain. To do this, you will need to know that the alpha-3 code for Great Britain is *GBR* and set the parameters like this:
Let's say you wanted to find museums in the state of **Texas**. You'd need to set the `boundary.rect.*` parameter grouping to values representing the bounding box around **Texas**: min_lon=-106.65 min_lat=25.84 max_lon=-93.51 max_lat=36.5
Sometimes you don't have a rectangle to work with, but rather you've got a point on earth, for example your location coordinates, and a maximum distance within which acceptable results can be located.
This time, we'll use the `boundary.circle.*` parameter grouping to get the job done. `boundary.circle.lat` and `boundary.circle.lon` should be set to your location in **Madrid**, while `boundary.circle.radius` should be set to the acceptable distance from that location. Note that the `boundary.circle.radius` parameter is always specified in **kilometers**.
If you're going to attempt using multiple boundary types in a single search request, be aware that the results will come from the **intersection** of all the boundaries! So if you provide regions that don't overlap, you'll be looking at an empty set of results. You've been warned. Here's a visual of how it works:
Many usecases call for the ability to surface nearby results to the front of the list, while still allow important matches from further away to be visible. If that's your conundrum, here's what you've got to do.
Search will focus on a given point anywhere on earth, and results within **~100km** will be prioritized higher, thereby surfacing highest in the list. Once all the nearby results have been found, additional results will come from the rest of the world, without any further location-based prioritization.
Looking at the results, you can see that the few locations closer to **Sydney** show up at the top of the list, sorted by distance. You also still get back a significant amount of remote locations, for a well balanced mix. Oh, and since you provided a focus point, we can now compute distance from that point for each result, so check that out in each feature.
> * YMCA, Redfern, New South Wales [distance: 3.836]
* YMCA, St Ives (NSW), New South Wales [distance: 14.844]
* YMCA, Epping (NSW), New South Wales [distance: 16.583]
* YMCA, Revesby, New South Wales [distance: 21.335]
Now that we've seen how to use boundary and focus to narrow down and sort your results, let's examine a few scenarios where they work well together.
### Prioritize within a country
**TBD: insert image here**
#### Example time
Let's revisit the YMCA search we conducted with a focus around the Sydney Opera House. When providing only `focus.point`, we saw results come back from distant parts of the world, as expected. But say you wanted to only see results from the country in which your focus point lies. Let's combine that same focus point, Sydney Opera House, with the country boundary of Australia. Check this out.
The results below look very different from the ones we saw previously with only a focus point specified. These results are all from within Australia. You'll note the closest results show up at the beginning of the list, which is facilitated by the focus parameter. Pretty spectacular, right!?
> * YMCA, Redfern, New South Wales [distance: 3.836]
* YMCA, St Ives (NSW), New South Wales [distance: 14.844]
* YMCA, Epping (NSW), New South Wales [distance: 16.583]
* YMCA, Revesby, New South Wales [distance: 21.335]
Let's say you're looking for the **nearest** YMCA locations, and are willing to travel no further than **50km** from your current location. You'd like the results to be sorted by distance from current location, in order to make your selection process easier. We can get this behavior by using `focus.point` in combination with `boundary.circle.*`. We can reuse the `focus.point.*` values as the `boundary.circle.lat` and `boundary.circle.lon`, and simply specify the required `boundary.circle.radius` value in kilometers.
Check out the results. They are all less than 50km away from the focus point:
> * YMCA, Redfern, New South Wales [distance: 3.836]
* YMCA, St Ives (NSW), New South Wales [distance: 14.844]
* YMCA, Epping (NSW), New South Wales [distance: 16.583]
* YMCA, Revesby, New South Wales [distance: 21.335]
* Caringbah YMCA, Caringbah, New South Wales [distance: 22.543]
* YMCA building, Loftus, New South Wales [distance: 25.756]
## Filtering your Search...
Mapzen search offers two types of options for selecting the dataset you want to search:
*`sources` : the originating source of the data
*`layers` : the kind of place you're looking to find
### ...by Data Source
Mapzen Search brings together data from various open sources. All the search examples we've seen so far, return a mix of results from all the different sources. Here's a list of what we import at this time:
We've added a helpful `sources` parameter to the Search API, to allow users to select which of these data sources they want to include in their search. So if you're only intersted in searching **OpenAddressses**, for example, your query would look as follows.
#### Example time
Let's search for **YMCA** again but only within the **OpenAddresses** data source.
If you wanted to combine several data sources together, you would simply set `sources` to a comma separated list of desired source names. Note that the order of the comma separated values does not impact sorting order of the results. They are still sorted based on the linguistic match quality to `text` and distance from `focus`, if one was specified.
Mapzen Search brings together a variety of place types into a single database. We refer to these place types as `layers`, and think of them as ranging from *fine* to *coarse*. Our layers are derived from the hierarchy created by the gazetteer [Who's on First](https://github.com/whosonfirst/whosonfirst-placetypes/blob/master/README.md) and can be used to facilitate *coarse* geocoding. Here's a list of the types of places you could find in our results, sorted by granularity:
Now that you've seen some examples of search, let's examine the results closer.
When requesting search results you will always get back `GeoJSON` results, unless something goes terribly wrong, in which case you'll get a really helpful error.
> _You can go [here](link.to.geojson.spec.com) to learn more about the `GeoJSON` data format specification.
> We'll assume you're familiar with the general layout and only point out some important details here._
You will find the following top-level structure to every response:
```javascript
{
"geocoding":{...},
"type":"FeatureCollection",
"features":[...],
"bbox":[...]
}
```
For the purposes of getting started quickly, let's keep our focus on the **features** property of the result.
This is where you will find the list of results that best matched your input parameters.
Each item in this list will contain all the information needed to identify it in human-readable format in the `properties` block, as well as computer friendly coordinates in the `geometry` property. Note the `label` property, which is a human-friendly representation of the place, ready to be displayed to an end-user.
```javascript
{
"type":"Feature",
"properties":{
"gid":"...",
"layer":"address",
"source":"osm",
"name":"30 West 26th Street",
"housenumber":"30",
"street":"West 26th Street",
"postalcode":"10010",
"country_a":"USA",
"country":"United States",
"region":"New York",
"region_a":"NY",
"county":"New York County",
"localadmin":"Manhattan",
"locality":"New York",
"neighbourhood":"Flatiron District",
"confidence":0.9624939994613662,
"label":"30 West 26th Street, Manhattan, NY"
},
"geometry":{
"type":"Point",
"coordinates":[
-73.990342,
40.744243
]
}
}
```
There is so much more to tell you about the plethora of data being returned for each search,
we had to split it out into its own section.
[Read more about the response format.](https://github.com/dianashk/pelias-doc/edit/master/getting-started/response.md)
## Result count
You may have noticed that there were **10** places in the results for all the previous search examples.