forked from CesiumGS/cesium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request CesiumGS#6453 from AnalyticalGraphicsInc/pelias
Add support for the Pelias geocoder
- Loading branch information
Showing
6 changed files
with
242 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
define([ | ||
'../Core/freezeObject' | ||
], function( | ||
freezeObject) { | ||
'use strict'; | ||
|
||
/** | ||
* The type of geocoding to be performed by a {@link GeocoderService}. | ||
* @exports GeocodeType | ||
* @see Geocoder | ||
*/ | ||
var GeocodeType = { | ||
/** | ||
* Perform a search where the input is considered complete. | ||
* | ||
* @type {Number} | ||
* @constant | ||
*/ | ||
SEARCH: 0, | ||
|
||
/** | ||
* Perform an auto-complete using partial input, typically | ||
* reserved for providing possible results as a user is typing. | ||
* | ||
* @type {Number} | ||
* @constant | ||
*/ | ||
AUTOCOMPLETE: 1 | ||
}; | ||
|
||
return freezeObject(GeocodeType); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
define([ | ||
'./Check', | ||
'./defined', | ||
'./defineProperties', | ||
'./GeocodeType', | ||
'./Rectangle', | ||
'./Resource' | ||
], function ( | ||
Check, | ||
defined, | ||
defineProperties, | ||
GeocodeType, | ||
Rectangle, | ||
Resource) { | ||
'use strict'; | ||
|
||
/** | ||
* Provides geocoding via a {@link https://pelias.io/|Pelias} server. | ||
* @alias PeliasGeocoderService | ||
* @constructor | ||
* | ||
* @param {Resource|String} url The endpoint to the Pelias server. | ||
* | ||
* @example | ||
* // Configure a Viewer to use the Pelias server hosted by https://geocode.earth/ | ||
* var viewer = new Cesium.Viewer('cesiumContainer', { | ||
* geocoder: new Cesium.PeliasGeocoderService(new Cesium.Resource({ | ||
* url: 'https://api.geocode.earth/v1/', | ||
* queryParameters: { | ||
* api_key: '<Your geocode.earth API key>' | ||
* } | ||
* })) | ||
* }); | ||
*/ | ||
function PeliasGeocoderService(url) { | ||
//>>includeStart('debug', pragmas.debug); | ||
Check.defined('url', url); | ||
//>>includeEnd('debug'); | ||
|
||
this._url = Resource.createIfNeeded(url); | ||
} | ||
|
||
defineProperties(PeliasGeocoderService.prototype, { | ||
/** | ||
* The Resource used to access the Pelias endpoint. | ||
* @type {Resource} | ||
* @memberof {PeliasGeocoderService.prototype} | ||
* @readonly | ||
*/ | ||
url: { | ||
get: function () { | ||
return this._url; | ||
} | ||
} | ||
}); | ||
|
||
/** | ||
* @function | ||
* | ||
* @param {String} query The query to be sent to the geocoder service | ||
* @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. | ||
* @returns {Promise<GeocoderResult[]>} | ||
*/ | ||
PeliasGeocoderService.prototype.geocode = function(query, type) { | ||
//>>includeStart('debug', pragmas.debug); | ||
Check.typeOf.string('query', query); | ||
//>>includeEnd('debug'); | ||
|
||
var resource = this._url.getDerivedResource({ | ||
url: type === GeocodeType.AUTOCOMPLETE ? 'autocomplete' : 'search', | ||
queryParameters: { | ||
text: query | ||
} | ||
}); | ||
|
||
return resource.fetchJson() | ||
.then(function (results) { | ||
return results.features.map(function (resultObject) { | ||
var bboxDegrees = resultObject.bbox; | ||
|
||
// Pelias does not always provide bounding information | ||
// so just expand the location slightly. | ||
if (!defined(bboxDegrees)) { | ||
var lon = resultObject.geometry.coordinates[0]; | ||
var lat = resultObject.geometry.coordinates[1]; | ||
bboxDegrees = [ | ||
lon - 0.001, | ||
lat - 0.001, | ||
lon + 0.001, | ||
lat + 0.001 | ||
]; | ||
} | ||
|
||
return { | ||
displayName: resultObject.properties.label, | ||
destination: Rectangle.fromDegrees(bboxDegrees[0], bboxDegrees[1], bboxDegrees[2], bboxDegrees[3]) | ||
}; | ||
}); | ||
}); | ||
}; | ||
|
||
return PeliasGeocoderService; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
defineSuite([ | ||
'Core/PeliasGeocoderService', | ||
'Core/GeocodeType', | ||
'Core/Rectangle', | ||
'Core/Resource', | ||
'ThirdParty/when' | ||
], function( | ||
PeliasGeocoderService, | ||
GeocodeType, | ||
Rectangle, | ||
Resource, | ||
when) { | ||
'use strict'; | ||
|
||
it('constructor throws without url', function() { | ||
expect(function() { | ||
return new PeliasGeocoderService(undefined); | ||
}).toThrowDeveloperError(); | ||
}); | ||
|
||
it('returns geocoder results', function () { | ||
var service = new PeliasGeocoderService('http://test.invalid/v1/'); | ||
|
||
var query = 'some query'; | ||
var data = { | ||
features: [{ | ||
type: "Feature", | ||
geometry: { | ||
type: "Point", | ||
coordinates: [-75.172489, 39.927828] | ||
}, | ||
properties: { | ||
label: "1826 S 16th St, Philadelphia, PA, USA" | ||
} | ||
}] | ||
}; | ||
spyOn(Resource.prototype, 'fetchJson').and.returnValue(when.resolve(data)); | ||
|
||
return service.geocode(query) | ||
.then(function(results) { | ||
expect(results.length).toEqual(1); | ||
expect(results[0].displayName).toEqual(data.features[0].properties.label); | ||
expect(results[0].destination).toBeInstanceOf(Rectangle); | ||
}); | ||
}); | ||
|
||
it('returns no geocoder results if Pelias has no results', function() { | ||
var service = new PeliasGeocoderService('http://test.invalid/v1/'); | ||
|
||
var query = 'some query'; | ||
var data = { features: [] }; | ||
spyOn(Resource.prototype, 'fetchJson').and.returnValue(when.resolve(data)); | ||
|
||
return service.geocode(query) | ||
.then(function(results) { | ||
expect(results.length).toEqual(0); | ||
}); | ||
}); | ||
|
||
it('calls search endpoint if specified', function () { | ||
var service = new PeliasGeocoderService('http://test.invalid/v1/'); | ||
|
||
var query = 'some query'; | ||
var data = { features: [] }; | ||
spyOn(Resource.prototype, 'fetchJson').and.returnValue(when.resolve(data)); | ||
var getDerivedResource = spyOn(service._url, 'getDerivedResource').and.callThrough(); | ||
|
||
service.geocode(query, GeocodeType.SEARCH); | ||
expect(getDerivedResource).toHaveBeenCalledWith({ | ||
url: 'search', | ||
queryParameters: { | ||
text: query | ||
} | ||
}); | ||
}); | ||
|
||
it('calls autocomplete endpoint if specified', function () { | ||
var service = new PeliasGeocoderService('http://test.invalid/v1/'); | ||
|
||
var query = 'some query'; | ||
var data = { features: [] }; | ||
spyOn(Resource.prototype, 'fetchJson').and.returnValue(when.resolve(data)); | ||
var getDerivedResource = spyOn(service._url, 'getDerivedResource').and.callThrough(); | ||
|
||
service.geocode(query, GeocodeType.AUTOCOMPLETE); | ||
expect(getDerivedResource).toHaveBeenCalledWith({ | ||
url: 'autocomplete', | ||
queryParameters: { | ||
text: query | ||
} | ||
}); | ||
}); | ||
}); |