Coder Social home page Coder Social logo

api's Introduction

A modular, open-source search engine for our world.

Pelias is a geocoder powered completely by open data, available freely to everyone.

Local Installation · Cloud Webservice · Documentation · Community Chat

What is Pelias?
Pelias is a search engine for places worldwide, powered by open data. It turns addresses and place names into geographic coordinates, and turns geographic coordinates into places and addresses. With Pelias, you’re able to turn your users’ place searches into actionable geodata and transform your geodata into real places.

We think open data, open source, and open strategy win over proprietary solutions at any part of the stack and we want to ensure the services we offer are in line with that vision. We believe that an open geocoder improves over the long-term only if the community can incorporate truly representative local knowledge.

Pelias API Server

This is the API server for the Pelias project. It's the service that runs to process user HTTP requests and return results as GeoJSON by querying Elasticsearch and the other Pelias services.

Documentation

Full documentation for the Pelias API lives in the pelias/documentation repository.

Install Dependencies

The Pelias API has no dependencies beyond Node.js

See Pelias Software requirements for the supported and recommended versions.

npm install

scripts

The API ships with several convenience commands (runnable via npm):

  • npm start: start the server
  • npm test: run unit tests
  • npm run ciao: run functional tests (this requires that the server be running)
  • npm run docs: generate API documentation
  • npm run coverage: generate code coverage reports
  • npm run config: dump the configuration to the command line, which is useful for debugging configuration issues

Configuration via pelias-config

To run the API with your custom config, specify the location of the config file in the environment variable PELIAS_CONFIG like so:

PELIAS_CONFIG=/path/to/pelias.json npm run start

The API recognizes the following properties under the top-level api key in your pelias.json config file:

parameter required default description
services no Service definitions for point-in-polygon, libpostal, placeholder, and interpolation services. For a description of when different Pelias services are recommended or required, see our services documentation.
defaultParameters.focus.point.lon
defaultParameters.focus.point.lat
no default coordinates for focus point
targets.auto_discover no true Should sources and layers be automatically discovered by querying Elasticsearch at process startup. (See more info in the Custom sources and layers section below).
targets.auto_discover_required no false If set to true, type mapping discovery failures will result in a fatal error. This means a valid connection to a working Elasticsearch cluster with a Pelias index is required on startup. Setting this to true can help prevent issues such as incorrect configuration in production environments
targets.layers_by_source
targets.source_aliases
targets.layer_aliases
no custom values for which sources and layers the API accepts (See more info in the Custom sources and layers section below). We recommend using the targets.auto_discover:true configuration instead of setting these manually.
customBoosts no {} Allows configuring boosts for specific sources and layers, in order to influence result order. See Configurable Boosts below for details
autocomplete.exclude_address_length no 0 As a performance optimization, this optional filter excludes results from the 'address' layer for any queries where the character length of the 'subject' portion of the parsed_text is equal to or less than this many characters in length. Addresses are usually the bulk of the records in Elasticsearch, and searching across all of them for very short text inputs can be slow, with little benefit. Consider setting this to 1 or 2 if you have several million addresses in Pelias.
indexName no pelias name of the Elasticsearch index to be used when building queries
attributionURL no (autodetected) The full URL to use for the attribution link returned in all Pelias responses. Pelias will attempt to autodetect this host, but it will often be incorrect if, for example, there is a proxy between Pelias and its users. This parameter allows setting a specific URL to avoid any such issues
accessLog no name of the format to use for access logs; may be any one of the predefined values in the morgan package. Defaults to "common"; if set to false, or an otherwise falsy value, disables access-logging entirely.
relativeScores no true if set to true, confidence scores will be normalized, realistically at this point setting this to false is not tested or desirable
exposeInternalDebugTools no true Exposes several debugging tools, such as the ability to enable Elasticsearch explain mode, that may come at a performance cost or expose sensitive infrastructure details. Not recommended if the Pelias API is open to the public.

A good starting configuration file includes this section (fill in the service and Elasticsearch hosts as needed):

{
  "esclient": {
    "hosts": [{
      "host": "elasticsearch"
    }]
  },
  "api": {
    "services": {
      "placeholder": {
        "url": "http://placeholder:4100"
      },
      "libpostal": {
        "url": "http://libpostal:8080"
      },
      "pip": {
        "url": "http://pip-service:4200",
        "timeout": 1000,
        "retries": 2
      },
      "interpolation": {
        "url": "http://interpolation:4300"
      }
    }
  },
  "logger": {
    "level": "debug"
  }
}

The timeout and retry values, as show in in the pip service section, are optional but configurable for all services (see pelias/microservice-wrapper for more details).

Custom sources and layers

Pelias allows importing your own data with custom values for source and layer.

Custom sources and layers are automatically detected on startup of the API. To disable this behavior (not recommended), set targets.auto_discover to false in your pelias.json.

The auto_discover functionality sends a request to Elasticsearch in order to automatically discover sources and layers from Elasticsearch when the API server starts-up.

In setups with lots of data (hundreds of millions of records loaded), and low CPU resources, the query sent to Elasticsearch can take several seconds to execute, potentially impacting the performance of other queries hitting Elasticsearch at the same time. The query is cached in Elasticsearch for subsequent requests.

In the rare event this causes issues, the following configuration options can be set to configure sources and layers by hand.

layers_by_source

This parameter tells Pelias what type of records it can expect a given datasource to have. Anything put here will extend the default configuration which handles all the open data project Pelias supports out of the box. The parameter is an object where your custom source names are the keys, and the list of layers in that source are the values in an array. For example, if you have two custom sources, mysource which contains addresses and countries, and mysource2 containing neighbourhoods, the following would work well:

"api": {
  "targets": {
    "layers_by_source": {
      "mysource": ["address", "country"],
      "mysource2": ["neighbourhood"]
    }
  }
}

source_aliases

An optional list of alternate names for sources. These 'aliases' are a convenient way to provide a short alias for a more verbose source name. An alias may refer to one or more sources. The keys on the left side represent a previously undefined 'alias', while the values in the array on the right refer to sources previously defined in "layers_by_source".

For example, to create an alias that allows conveniently searching the two open data projects who's name starts with "Open", use the following configuration:

{
  "api": {
    "targets": {
      "source_aliases": {
        "opensomething": [ "openstreetmap", "openaddresses" ]
    }
  }
}

layer_aliases

An optional list of alternate names for layers. These 'aliases' are a convenient way to provide a short alias for a more verbose layer name. An alias may refer to one or more layers. The keys on the left side represent a previously undefined 'alias', while the values in the array on the right refer to layers previously defined in "layers_by_source"

For example, to create a layer alias water that represents all the water layer types supported by Pelias:

{
  "api": {
    "targets": {
      "layer_aliases": {
        "water": [ "ocean", "marinearea" ]
    }
  }
}

Custom Boosts

The customBoosts config section allows influencing the sorting of results returned from most Pelias queries. Every Pelias record has a source and layer value, and this section allows prioritizing certain sources and layers.

First, keep in mind:

  1. This will not affect all Pelias queries. In particular, when using the /v1/search endpoint, queries for administrative areas (cities, countries, etc) will likely not be affected
  2. Custom boosts allow influencing results, but not completely controlling them. Very good matches that aren't in a boosted source or layer may still be returned first.

The basic form of the configuration looks like this:

{
  "api":
    "customBoosts": {
      "layer": {
        "layername": 5,
        "layername2": 3
      },
      "source": {
        "sourcename": 5
      }
    }
  }
}

There are subsections for both layer and source, and each subsection must be an object. Keys in those objects represent the sources and layers to be boosted, and the value associated with those keys must be a numeric value.

Boost values are essentially multipliers, so values greater than 1 will cause a source or layer to be returned more often, and higher in results. Boosts of the value 1 are the same as no boost, and boosts between 0 and 1 will de-prioritize matching records.

Recommended boost values are between 1 and 5. Higher boosts are likely to cause unexpected impact without really improving results much.

Configuration via Environment variable

Most Pelias configuration is done through pelias-config, however the API has additional environment variables that affect its operation:

environment variable default description
HOST undefined The network interface the Pelias API will bind to. Defaults to whatever the current Node.js default is, which is currently to listen on all interfaces. See the Node.js Net documentation for more info.
PORT 3100 The TCP port the Pelias API will use for incoming network connections.

Contributing

Please fork and pull request against upstream master on a feature branch. Pretty please; provide unit tests and script fixtures in the test directory.

Unit tests

You can run the unit test suite using the command:

$ npm test

HTTP tests

We have another set of tests which are used to test the HTTP API layer, these tests send expected HTTP requests and then assert that the responses coming back have the correct geoJSON format and HTTP status codes.

You can run the HTTP test suite using the command:

$ npm run ciao

Note: some of the tests in this suite fail when no data is present in the index, there is a small set of test documents provided in ./test/ciao_test_data which can be inserted in order to avoid these errors.

To inject dummy data in to your local index:

$ node test/ciao_test_data.js

You can confirm the dummy data has been inserted with the command:

$ curl localhost:9200/pelias/_count?pretty
{
  "count" : 9,
  ...
}

Continuous Integration

CI tests every release against all supported Node.js versions.

api's People

Contributors

antoine-de avatar avulfson17 avatar blackmad avatar dianashk avatar echelon9 avatar gitter-badger avatar greenkeeper[bot] avatar greenkeeperio-bot avatar hannesj avatar heffergm avatar hkrishna avatar joxit avatar mihneadb avatar missinglink avatar orangejulius avatar pmezard avatar rabidllama avatar riordan avatar sevko avatar stephenlacy avatar stvno avatar sweco-semhul avatar tadjik1 avatar thismakessand avatar tigerlily-he avatar tpedelose avatar trescube avatar vanessayuenn avatar vesameskanen avatar worace avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

api's Issues

suggest nearby oddities

http://pelias.mapzen.com/suggest/nearby?input=a&lat=51.5328850&lon=-0.0652280

lat/lon is for: London, UK.

I would expect to see more than one result and results more similar to /search

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "id": "6255146",
        "type": "geoname",
        "layer": "geoname",
        "name": "Africa",
        "text": "Africa"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          21.09375,
          7.1881
        ]
      }
    }
  ],
  "bbox": [
    21.09375,
    7.1881,
    21.09375,
    7.1881
  ],
  "date": 1427141000665
}

Use categories as a scoring function

Each point has a field called category that contains some valuable information, it would be nice to use this information in the scoring algorithm.

We could have a file weighted_categories.yml where we can define what weight each tag value corresponds to.

   airport: 12
   railway: 10
   restaurant: 8
   tourism: 11
   poi:landmark: 10
   ...

This should be a query time boosting easily do-able by just adding a script and using it in the API sorting logic.

Related to pelias/openstreetmap#33 and pelias/pelias#50

security: express middleware

investigate https://github.com/evilpacket/helmet and possibly talk to adam.

this ticket is to review the helmet npm module and establish if including some of their functionality in our app will decrease the risk of malicious attack.

security is always important, we are only storing open data which is freely available anyway and no personal data so theft is not an issue but we have a responsibility to ensure security for our users as best we can.

"express is a very thin http framework, the heavy lifting is done by the middleware and their philosophy continues to be to have as little as possible enabled by default"

layer aliases

it might be nice to have 'aliases' for the 'layers' param.

eg.
?layers=poi could expand to ['geoname','osmnode','osmway'] and
?layers=admin could expand to ['admin0','admin1','admin2','neighborhood']

this may do away with the need for multiple suggester endpoints?

@hkrishna thoughts?

API (possibly express) swallows runtime exceptions

The API appears to silently swallow runtime exceptions that would otherwise cause it to print a stack trace and crash. For instance, I've changed query/search.js:17 from:

var query = queries.distance( centroid, { size: params.size } );

to

var query = queries.distance( centroid, { size: param.size } );

Note that params.size became param.size, and, because param doesn't exist, you'd expect the process to crash with ReferenceError: param is not defined. When running the API via node index.js, however:

$ curl localhost:3100/search?input=foobar
{"error":{}}

The request obviously errored and the status code is 500, yet the API keeps running without any output besides listening on 3100. If you try to use the query/search module directly, on the other hand, it errors as expected:

$ node -e 'console.log(require("./query/search")({}));'
/home/sevko/src/mapzen/api/query/search.js:17
  var query = queries.distance( centroid, { size: param.size } );
                                                  ^
ReferenceError: param is not defined
    at generate (/home/sevko/src/mapzen/api/query/search.js:17:51)
    at [eval]:1:38
    at Object.exports.runInThisContext (vm.js:74:17)
    at Object.<anonymous> ([eval]-wrapper:6:22)
    at Module._compile (module.js:460:26)
    at evalScript (node.js:431:25)
    at startup (node.js:90:7)
    at node.js:814:3

caching strategy / etags

The API etags are messed up because of the date property in the body changing all the time.

The etag should be the same for the same content.

A few fixes come to mind:

  1. move date to header, may be hard for ajax consumers to deal with
  2. remove date, will be hard for frontends to handle stale /suggest requests
  3. manually compute the etag then add the date
  4. something else

Personally; I would prefer to completely drop etags in favour of max-age headers as they are more performant due to making far less network requests and they are well suited for content which doesn't change often.

With any solution there will be an issue with the date property; which exists to ensure that database & network congestion doesn't cause older requests to change the UI after a newer request has already been received and rendered.

Some serious thought needs to go in to ideal cache control strategies; which account for near-side and far-side caching, mobile experience and typeahead UI.

ref: http://vadmyst.blogspot.de/2005/09/server-side-etag-vs-cache-control-max.html

add logging

use winston or another similar logging library

input text interpretation

When entering location strings where the text is delimited by a symbol, eg. 'London, UK' or 'London, ON' the context suggester fails to see the difference between the named component and the admin component(s) which are conventionally delimited using a comma.

We need to start looking at some very basic NLP even if it's just something like only using the tokens before the first comma.

Here's a visual illustration of the problem:
ss

The gifs shows 2 UX issues:

  1. Not reproducible: when clicking a successful match you cannot use the string returned to search and find that same place, you must remove everything after the first comma.
  2. You cannot paste an address string directly in to the input, eg. pasting "Hackney Town Hall, Hackney, Greater London" yields 0 results.

thoughts @hkrishna ?

note, to reproduce the above query bias: https://mapzen.com/pelias#loc=18,51.54503,-0.05639

filter by alpha3

it might be nice to allow consumers to restrict the results returned to only those which lie within an alpha3.

ie. I want an autocomplete for admin records in GBR.

outputGenerator tweaks

In the following example, the 'text' should be 'Arbil, Iraq' but due to the way the outputGenerator is written it matches nothing for local and 'Arbil' for regional (the name is also 'Arbil').

If I simply add admin1 to the end of the local array then both local and regional will match 'Arbil' and when the de-duper removes one entry, we are back with the text being 'Arbil'.

Not sure if I described this well, but basically we need to continue checking values in the local and regional arrays until we find a value which is not a duplicate of the name or another admin value, otherwise a POI with { "name": "a", "local_admin": "a", "admin1_abbr": "a", "admin0": "b" } will always just be a when it would be nicer if it were a, b.

Hope that makes sense ;)

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          44.180874,
          36.369878
        ]
      },
      "properties": {
        "id": "1110:adm1:iq:irq:arbil",
        "type": "admin1",
        "layer": "admin1",
        "name": "Arbil",
        "alpha3": "IRQ",
        "admin0": "Iraq",
        "admin1": "Arbil",
        "text": "Arbil"
      }
    },
...

Inconsistent Autocomplete

This UX issue is somewhat subjective, so I'll try to explain why I think it is a problem.

Consider the gif below:
ss

As the amount of characters are added to the query "Hackney City Farm" we get very different results back, those results differ both in which layers the data comes from; the ratio of local/distant entries and the total amount of items returned.

For all characters up to and including "hackney " we only get administrative entries returned, I personally think this is fine with the exception of a large amount of distant or low population admin entries that appear before your first word is completely formed.

When you reach 8 characters, eg. "hackney c" you seem to get an odd mix of admin entries and places, this is also where some entries from over 6000km appear in the results.

When you type "hackney ci" you don't get any results at all? I find this behaviour very odd and it seems like a bug?

After typing "hackney cit" or more characters the correct local POI is returned.

note, to reproduce the above query bias: https://mapzen.com/pelias#loc=18,51.54503,-0.05639

cc/ @pelias/owners

[operations] Domain Root

Currently when you hit the domain root http://pelias.mapzen.com/ it serves a plain white HTML page, this is the same behaviour for 404 error pages.

Recently we have been adding the root URL to documentation, notably here: https://github.com/pelias/pelias#im-a-developer-can-i-get-access-to-the-api

Couple questions:

  1. Should all endpoints return application/json?
  2. What should be served at the domain root for the pelias service?
  3. What should be served in case of 404 errors; what encoding?

boost results by query locality

A query for 1710 Drew, Houston currently ranks 1710 Drew Place, Claremont, CA higher than 1710 Drew Street, Houston, TX. According to @hkrishna , we only boost matches for admin0, admin1, and admin1_abbr, meaning that the exact locality match doesn't get taken into account at all here. We should factor it into boosting if it doesn't significantly impact query times.

suggest and reverse problems

I'm having a hard time getting the API to work properly, and also understanding which components I actually need. I changed the layers URL in the demo to work with our maps. This works. I also changed the API URL to our installation, but it will only show search results.
Suggest queries don't return anything

{"type":"FeatureCollection","features":[],"date":1427269933035}

reverse actually returns an error
TypeError: Cannot read property 'geometry' of undefined at demo.js:145 at angular.js:8598 at angular.js:12234 at k.$eval (angular.js:13436) at k.$digest (angular.js:13248) at k.$apply (angular.js:13540) at q (angular.js:8884) at u (angular.js:9099) at XMLHttpRequest.E.onreadystatechange (angular.js:9038)angular.js:10683 (anonymous function)angular.js:7858 (anonymous function)angular.js:12242 (anonymous function)angular.js:13436 k.$evalangular.js:13248 k.$digestangular.js:13540 k.$applyangular.js:8884 qangular.js:9099 uangular.js:9038 E.onreadystatechange

This is from a search query:

{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"288998480","layer":"osmway","name":"Wien","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Mariabrunn","text":"Wien"},"geometry":{"type":"Point","coordinates":[16.244355,48.201155]}},{"type":"Feature","properties":{"id":"8091317","layer":"osmnode","name":"Wien Ottakring","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Breitensee","text":"Wien Ottakring, Wien"},"geometry":{"type":"Point","coordinates":[16.311194,48.211817]}},{"type":"Feature","properties":{"id":"8091320","layer":"osmnode","name":"Wien Hernals","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Dornbach","text":"Wien Hernals, Wien"},"geometry":{"type":"Point","coordinates":[16.31483,48.223272]}},{"type":"Feature","properties":{"id":"8091331","layer":"osmnode","name":"Wien Gersthof","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Gersthof","text":"Wien Gersthof, Wien"},"geometry":{"type":"Point","coordinates":[16.329063,48.230864]}},{"type":"Feature","properties":{"id":"8091423","layer":"osmnode","name":"Wien Heiligenstadt","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Nuszdorf","text":"Wien Heiligenstadt, Wien"},"geometry":{"type":"Point","coordinates":[16.365545,48.248981]}},{"type":"Feature","properties":{"id":"9232378","layer":"osmnode","name":"Wien Jedlersdorf","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Neujedlersdorf","text":"Wien Jedlersdorf, Wien"},"geometry":{"type":"Point","coordinates":[16.395964,48.274071]}},{"type":"Feature","properties":{"id":"9232410","layer":"osmnode","name":"Wien Floridsdorf","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Neujedlersdorf","text":"Wien Floridsdorf, Wien"},"geometry":{"type":"Point","coordinates":[16.400016,48.256354]}},{"type":"Feature","properties":{"id":"9232449","layer":"osmnode","name":"Wien Traisengasse","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Brigittenau","text":"Wien Traisengasse, Wien"},"geometry":{"type":"Point","coordinates":[16.383248,48.234871]}},{"type":"Feature","properties":{"id":"9232502","layer":"osmnode","name":"Wien Strebersdorf","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Schwarzlackenausiedlung","text":"Wien Strebersdorf, Wien"},"geometry":{"type":"Point","coordinates":[16.381598,48.285661]}},{"type":"Feature","properties":{"id":"27024450","layer":"osmnode","name":"Wien Simmering","alpha3":"AUT","admin0":"Austria","admin1":"Wien","admin2":"Wien","locality":"Wien","neighborhood":"Simmering","text":"Wien Simmering, Wien"},"geometry":{"type":"Point","coordinates":[16.419459,48.170099]}}],"bbox":[16.244355,48.170099,16.419459,48.285661],"date":1427278983264}

Using the vagrant image is not an option for me, I need to integrate this into our infrastructure properly.

Any pointers what I could be missing?

pretty-format results with a `pretty` parameter

It'd be great if the API could optionally pretty-format JSON via a parameter like pretty, so that users would be able to see this when curling it:

{
    "bbox": [
        -73.993641,
        40.721969,
        -73.993641,
        40.721969
    ],
    "date": 1427901010432,
    "features": [
        {
            "geometry": {
                "coordinates": [
                    -73.993641,
                    40.721969
                ],
                "type": "Point"
            },
            "properties": {
                "admin0": "United States",
                "admin1": "New York",
                "admin2": "New York",
                "alpha3": "USA",
                "id": "2ed31dafbbb9419da585e24a29550ce5",
                "layer": "openaddresses",
                "local_admin": "Manhattan",
                "locality": "New York",
                "name": "220 Bowery",
                "neighborhood": "Downtown",
                "text": "220 Bowery, Manhattan, New York",
                "type": "openaddresses"
            },
            "type": "Feature"
        }
    ],
    "type": "FeatureCollection"
}

rather than:

{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"2ed31dafbbb9419da585e24a29550ce5","type":"openaddresses","layer":"openaddresses","name":"220 Bowery","alpha3":"USA","admin0":"United St
ates","admin1":"New York","admin2":"New York","local_admin":"Manhattan","locality":"New York","neighborhood":"Downtown","text":"220 Bowery, Manhattan, New York"},"geometry":{"type":"Point","coordinates":[-73.99364
1,40.721969]}}],"bbox":[-73.993641,40.721969,-73.993641,40.721969],"date":1427901003524}

without having to pipe it through something like python -m json.tool. It'd make command-line examples cleaner.

Specific queries result in 5xx error responses and/or timeouts

Example:

time curl -v "http://pelias.mapzen.com/reverse?&input=a&lat=0&lon=0"
* Hostname was NOT found in DNS cache
*   Trying 54.88.134.185...
* Connected to pelias.mapzen.com (54.88.134.185) port 80 (#0)
> GET /reverse?&input=a&lat=0&lon=0 HTTP/1.1
> User-Agent: curl/7.37.1
> Host: pelias.mapzen.com
> Accept: */*
>
< HTTP/1.1 503 Service Unavailable
< Date: Thu, 26 Mar 2015 17:53:31 GMT
* Server Jetty(9.2.z-SNAPSHOT) is not blacklisted
< Server: Jetty(9.2.z-SNAPSHOT)
< Via: 1.1 Repose (Repose/6.2.1.2)
< Content-Length: 0
< Connection: keep-alive
<
* Connection #0 to host pelias.mapzen.com left intact

real    0m3.954s
user    0m0.004s
sys 0m0.005s

Feedback endpoint

Pelias API should have an endpoint where in, a client could give feedback on what the query was and what result item the user selected/used. This information can be helpful in populating our acceptance test cases and generally useful in refining the search quality.

params:

  • input Ex: 123 Main St, New York
  • resultSelected Ex: 123 Main St, Manhattan, NY (text/object?)
  • resultIndex Ex: 1 (number)

Bounding box support for /suggest

/suggest should be able to take in a bbox parameter and return suggestions that are contained within the given bounding box.

Here is a use-case provided by @mattkrick in pelias/pelias#81

"For my app, I'd like to autocomplete from a list of schools in a given town. If I use the suggest endpoint, I get suggestions from the other side of the country, but if I use the search endpoint with a bbox, it can't predict things mid-word. I think this could be best solved with a bbox on the suggest endpoint."

resolves: pelias/pelias#81

Address Schema Parameter

Let the user decide what version of output text they would like through the API. Perhaps an additional optional parameter lets say addressParts.

  • &addressParts=all (by default): will return name, local, regional, national as defined in outputSchema.json Ex: Arbil, Lye, West Midlands, GBR
  • &addressParts=local,regional: will return name, local, regional Ex: Arbil, Lye, West Midlands

We can also push this one step further and define formats for mobile &addressParts=mobile in a config file which will cater to smaller screens.

This issue is opened as a product of the ongoing discussions at #93

/suggest 'layers' params

as per #22 we should allow consumers to filter suggestions by layer on '/suggest' as they do on '/search'.

We have the 'dataset' category context suggester already set up to allow this.

Specify properties to send back in results

@baldur mentioned that it'd be useful to allow cherry-picking the properties returned by the API to reduce payload size. For instance, you could limit the following:

{
    "geometry": {
        "coordinates": [
            -73.94958,
            40.6501
        ],
        "type": "Point"
    },
    "properties": {
        "admin0": "United States",
        "admin1": "New York",
        "admin2": "Kings County",
        "alpha3": "USA",
        "id": "5110302",
        "layer": "geoname",
        "name": "Brooklyn",
        "text": "Brooklyn, Kings County, New York",
        "type": "geoname"
    },
    "type": "Feature"
}

to

{
    "geometry": {
        "coordinates": [
            -73.94958,
            40.6501
        ],
        "type": "Point"
    },
    "properties": {
        "admin0": "United States",
        "admin1": "New York",
        "admin2": "Kings County",
        "text": "Brooklyn, Kings County, New York",
        "type": "geoname"
    },
    "type": "Feature"
}

Add boundary.country parameter to /search and /reverse endpoints

The geometry of some country polygons makes it difficult to use bbox filtering to exclude neighbouring nations.

It would be nice to have an API param called alpha3 or similar which excluded results from outside that country.

When used in combination with a coarse geocoder it would be very easy to create a coarse search for a single country using the mapzen service.

SearchPhaseExecutionException

On the current master branch with the latest pelias-schema installed, I get the following errors when running the functional tests:

@hkrishna what's going on here!!?

 GET http://localhost:3100/search?input=lake&lat=29.49136&lon=-82.50622 test/ciao/search/success.coffee 
 ✘ valid response
 expected { message: 'SearchPhaseExecutionException[Failed to execute phase [query_fetch], all shards failed; shardFailures {[fDpHOdhCTM6AMkcFNpc1tg][pelias][0]: SearchParseException[[pelias][0]: query[filtered(name.default:lake)->BooleanFilter(+cache(GeoDistanceFilter(center_point, PLANE, 50000.0, 29.49, -82.51)))],from[-1],size[10]: Parse Failure [Failed to parse source [{"query":{"filtered":{"query":{"query_string":{"query":"lake","fields":["name.default"],"default_operator":"OR"}},"filter":{"bool":{"must":[{"geo_distance":{"distance":"50km","distance_type":"plane","optimize_bbox":"indexed","_cache":true,"center_point":{"lat":"29.49","lon":"-82.51"}}}]}}}},"size":10,"sort":["_score",{"_geo_distance":{"center_point":{"lat":29.49136,"lon":-82.50622},"order":"asc","unit":"km"}},{"_script":{"file":"admin_boost","type":"number","order":"desc"}},{"_script":{"file":"population","type":"number","order":"desc"}},{"_script":{"params":{"weights":{"geoname":0,"address":4,"osmnode":6,"osmway":6,"poi-address":8,"neighborhood":10,"local_admin":12,"locality":12,"admin2":12,"admin1":14,"admin0":2}},"file":"weights","type":"number","order":"desc"}}],"track_scores":true}]]]; nested: ElasticsearchIllegalArgumentException[Unable to find on disk script admin_boost]; }]' } to not exist

Search/Filter by Category

Related to pelias/openstreetmap#33 and pelias/pelias#50

This issue deals with using the category mapped on a document. Here are a few use cases:

  • find all airports in a bbox
  • search for a transit station
  • find the 10 nearest mexican restaurants

The API should be able to take a parameter lets say category and based on its value - use it in the queries as a filter. For example:

localhost:3100/search?input=maysville&category=restaurant

should return restaurants that are named maysville

localhost:3100/reverse?lat=0&lon=0&category=restaurant:mexican

should return the nearest mexican restaurants to lat/lon 0,0

only reverse-geocode against boundaries at high zoom levels

Would it make sense to only reverse-geocode against administrative boundaries at very high zoom levels? For instance, clicking around the center of the US at zoom level 3 returns:

{
    "geometry": {
        "coordinates": [
            -100.75994,
            38.30442
        ],
        "type": "Point"
    },
    "properties": {
        "admin0": "United States",
        "admin1": "Kansas",
        "admin2": "Scott County",
        "alpha3": "USA",
        "id": "5445311",
        "layer": "geoname",
        "name": "Dry Lake",
        "text": "Dry Lake, Scott County, Kansas",
        "type": "geoname"
    },
    "type": "Feature"
}

I feel like that's too granular, and a country/state result like the following might be more intuitive:

{
    "geometry": {
        "coordinates": [
            0.314297,
            45.153259
        ],
        "type": "Point"
    },
    "properties": {
        "admin0": "United States",
        "alpha3": "USA",
        "id": "329:adm0:us:usa:_",
        "layer": "admin0",
        "name": "United States",
        "text": "United States",
        "type": "admin0"
    },
    "type": "Feature"
}

Address details Parameter

If a user wants to just use the text property in the output and doesnt care about the rest - then he/she should be able to request a smaller payload by setting a parameter lets say addressDetails to false

Currently, each point that gets returned by the API looks like the following

{  
   type:"Feature",
   properties:{  
      id:"127099401",
      layer:"osmway",
      name:"Mays",
      alpha3:"GBR",
      admin0:"United Kingdom",
      admin1:"Bournemouth",
      admin2:"Dorset",
      locality:"Bournemouth",
      neighborhood:"Westbourne",
      text:"Mays, Westbourne, Dorset"
   },
   geometry:{  
      type:"Point",
      coordinates:[  
         -1.902019,
         50.721979
      ]
   }
}

with &addressDetails=false parameter, the output is slimmed down to the following

{  
   type:"Feature",
   properties:{  
      text:"Mays, Westbourne, Dorset"
   },
   geometry:{  
      type:"Point",
      coordinates:[  
         -1.902019,
         50.721979
      ]
   }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.