Skip to content

Commit

Permalink
Merge pull request #217 from Esri/patch216
Browse files Browse the repository at this point in the history
refactor(reorganizing): break up geocoding package into multiple files
  • Loading branch information
jgravois authored Jun 12, 2018
2 parents 78f5faf + 4acd4d1 commit 0cc7aaa
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 436 deletions.
11 changes: 10 additions & 1 deletion packages/arcgis-rest-geocoder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@ import { geocode } from '@esri/arcgis-rest-geocoder';

geocode("LAX")
.then((response) => {
response.candidates[0].location; // => { x: -118.409, y: 33.943, spatialReference: { wkid: 4326 } }
response.candidates[0].location;
// => { x: -118.409, y: 33.943 }
});
```

### [API Reference](https://esri.github.io/arcgis-rest-js/api/geocoder/)

* [`geocode("1 World Way Los Angeles 90045")`](https://esri.github.io/arcgis-rest-js/api/geocoder/geocode/)

* [`suggest("Starb")`](https://esri.github.io/arcgis-rest-js/api/geocoder/suggest/)

* [`reverseGeocode([-118.409,33.943 ])`](https://esri.github.io/arcgis-rest-js/api/geocoder/reverseGeocode/)

* [`bulkGeocode()`](https://esri.github.io/arcgis-rest-js/api/geocoder/bulkGeocode/)

### Issues

If something isn't working the way you expected, please take a look at [previously logged issues](https://github.com/Esri/arcgis-rest-js/issues) first. Have you found a new bug? Want to request a new feature? We'd [**love**](https://github.com/Esri/arcgis-rest-js/issues/new) to hear from you.
Expand Down
102 changes: 102 additions & 0 deletions packages/arcgis-rest-geocoder/src/bulk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* Copyright (c) 2017 Environmental Systems Research Institute, Inc.
* Apache-2.0 */

import { request } from "@esri/arcgis-rest-request";

import { ISpatialReference, IPoint } from "@esri/arcgis-rest-common-types";

import { worldGeocoder, IEndpointRequestOptions } from "./helpers";

// it'd be better if doc didnt display these properties in alphabetical order
export interface IAddressBulk {
/**
* A unique id must be passed along for each individual address.
*/
OBJECTID: number;
address?: string;
address2?: string;
address3?: string;
neighborhood?: string;
city?: string;
subregion?: string;
/**
* The World Geocoding Service considers US states regions.
*/
region?: string;
postal?: number;
postalExt?: number;
countryCode?: string;
}

export interface IBulkGeocodeRequestOptions extends IEndpointRequestOptions {
addresses: IAddressBulk[];
}

export interface IBulkGeocodeResponse {
spatialReference: ISpatialReference;
locations: Array<{
address: string;
location: IPoint;
score: number;
attributes: object;
}>;
}

/**
* Used to geocode a batch of addresses
*
* ```js
* import { bulkGeocode } from '@esri/arcgis-rest-geocoder';
* import { ApplicationSession } from '@esri/arcgis-rest-auth';
*
* const addresses = [
* { "OBJECTID": 1, "SingleLine": "380 New York Street 92373" },
* { "OBJECTID": 2, "SingleLine": "1 World Way Los Angeles 90045" }
* ];
*
* bulkGeocode({ addresses, authentication: session })
* .then((response) => {
* response.locations[0].location; // => { x: -117, y: 34, spatialReference: { wkid: 4326 } }
* });
* ```
*
* @param requestOptions - Request options to pass to the geocoder, including an array of addresses and authentication session.
* @returns A Promise that will resolve with the data from the response.
*/
export function bulkGeocode(
requestOptions: IBulkGeocodeRequestOptions // must POST
) {
const options: IBulkGeocodeRequestOptions = {
endpoint: worldGeocoder,
params: {
forStorage: true,
addresses: { records: [] }
},
...requestOptions
};

requestOptions.addresses.forEach(address => {
options.params.addresses.records.push({ attributes: address });
});

// the SAS service doesnt support anonymous requests
if (!requestOptions.authentication && options.endpoint === worldGeocoder) {
return Promise.reject(
"bulk geocoding using the ArcGIS service requires authentication"
);
}

return request(options.endpoint + "geocodeAddresses", options).then(
response => {
const sr = response.spatialReference;
response.locations.forEach(function(address: { location: IPoint }) {
address.location.spatialReference = sr;
});
return response;
}
);
}

export default {
bulkGeocode
};
117 changes: 117 additions & 0 deletions packages/arcgis-rest-geocoder/src/geocode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* Copyright (c) 2017 Environmental Systems Research Institute, Inc.
* Apache-2.0 */

import { request, IParams } from "@esri/arcgis-rest-request";

import {
IExtent,
ISpatialReference,
IPoint
} from "@esri/arcgis-rest-common-types";

import { worldGeocoder, IEndpointRequestOptions } from "./helpers";

export interface IGeocodeParams extends IParams {
/**
* You can create an autocomplete experience by making a call to suggest with partial text and then passing through the magicKey and complete address that are returned to geocode.
* ```js
* import { suggest, geocode } from '@esri/arcgis-rest-geocoder';
* suggest("LAX")
* .then((response) => {
* response.suggestions[2].magicKey; // => "dHA9MCNsb2M9Mjk3ODc2MCNsbmc9MzMjcGw9ODkxNDg4I2xicz0xNDoxNDc4MTI1MA=="
* });
* geocode("LAX, 1 World Way, Los Angeles, CA, 90045, USA", {magicKey: "dHA9MCN..."})
* ```
*/
magicKey?: string;
}

export interface IGeocodeRequestOptions extends IEndpointRequestOptions {
address?: string;
address2?: string;
address3?: string;
neighborhood?: string;
city?: string;
subregion?: string;
/**
* The World Geocoding Service expects US states to be passed in as a 'region'.
*/
region?: string;
postal?: number;
postalExt?: number;
countryCode?: string;
}

export interface IGeocodeResponse {
spatialReference: ISpatialReference;
candidates: Array<{
address: string;
location: IPoint;
extent: IExtent;
attributes: object;
}>;
}

/**
* Used to determine the location of a single address or point of interest
*
* ```js
* import { geocode } from '@esri/arcgis-rest-geocoder';
*
* geocode("LAX")
* .then((response) => {
* response.candidates[0].location; // => { x: -118.409, y: 33.943, spatialReference: { wkid: 4326 } }
* });
*
* geocode({
* params: {
* address: "1600 Pennsylvania Ave",
* postal: 20500,
* countryCode: "USA"
* }
* })
* .then((response) => {
* response.candidates[0].location; // => { x: -77.036533, y: 38.898719, spatialReference: { wkid: 4326 } }
* });
* ```
*
* @param address String representing the address or point of interest or RequestOptions to pass to the endpoint.
* @returns A Promise that will resolve with address candidates for the request.
*/
export function geocode(
address: string | IGeocodeRequestOptions
): Promise<IGeocodeResponse> {
let options: IGeocodeRequestOptions = {
endpoint: worldGeocoder,
params: {}
};

if (typeof address === "string") {
options.params.singleLine = address;
} else {
options.endpoint = address.endpoint || worldGeocoder;
options = {
...options,
...address
};
}

// add spatialReference property to individual matches
return request(options.endpoint + "findAddressCandidates", options).then(
response => {
const sr = response.spatialReference;
response.candidates.forEach(function(candidate: {
location: IPoint;
extent: IExtent;
}) {
candidate.location.spatialReference = sr;
candidate.extent.spatialReference = sr;
});
return response;
}
);
}

export default {
geocode
};
Loading

0 comments on commit 0cc7aaa

Please sign in to comment.