Geocode CSV in JavaScript

4389
12
Jump to solution
09-05-2014 07:43 AM
HeathAnderson
Occasional Contributor

I am trying to geocode a list of addresses from a CSV.  I know that there is a drag and drop option that works well if you have lat long, but I only have addresses.  I want my coworkers to be able to save an xls as a csv then in the JS app browse to the CSV and run the gp model or drag and drop the csv into the map and kickoff the gp tool.  The service is upload enabled, but I am struggling getting the correct code down.  Has anyone done this before where they can point me in the correct direction.

Cheers,

Heath

0 Kudos
1 Solution

Accepted Solutions
PaulCrickard1
Occasional Contributor II

This uses Leaflet.js and makes an AJAX call to your GIS Service on ArcServer. Just change the URL to the location of your service. You can drag the textfile to the map and it will put markers on the map. And change the map center coordinates so it is where you want to be. Mine is in Albuquerque. This uses Drag and Drop functionality in HTML5 so you need a new browser - just use chrome.

My address file looks like this:

7520 Corona Ave NE

600 2nd St NW

6200 Paseo Del-Norte

3805 Northern Blvd NE

3701 Constitution Ave NE

320 Yale Boulevard SE

6001 Lomas Blvd NE

My HTML File:

<html>

<head>

  <title></title>

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />

<style>

#map{

height: 100%;

width:100%;

}

</style>

</head>

<body>

<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>

<div id="map" ></div>

<script>

var map = L.map('map',

{

center: [35.10418, -106.62987],

zoom: 9

});

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);

  function handleFileSelect(evt) {

    evt.stopPropagation();

    evt.preventDefault();

    var files = evt.dataTransfer.files; // FileList object.

    var reader = new FileReader(); 

    reader.onload = function(event) {          

      

var temp=event.target.result;

var text=temp.replace( /\n/g, "," );

var c=text.split(",");

for(i=0;i<c.length;i++){

url1="http://YourDomain/ArcGIS/rest/services/AddressLocator/GeocodeServer/findAddressCandidates?Street=";

url2=String(c);

url3="&outFields=&outSR=4326&f=pjson";

url=url1.concat(url2,url3);

var xhReq = new XMLHttpRequest();

xhReq.open("GET", url, false);

xhReq.send(null);

var serverResponse = xhReq.responseText;

var d=JSON.parse(serverResponse);

if(typeof d.candidates[0] == 'undefined'){alert("error in address: "+url2);}

else{

L.marker([parseFloat(d.candidates[0].location.y),parseFloat(d.candidates[0].location.x)]).addTo(map).bindPopup(url2);

}

}

    }       

     var s = reader.readAsText(files[0],"UTF-8");

  }

  function handleDragOver(evt) {

    evt.stopPropagation();

    evt.preventDefault();

    evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.

  }

  // Setup the dnd listeners.

  var dropZone = document.getElementById('map');

  dropZone.addEventListener('dragover', handleDragOver, false);

  dropZone.addEventListener('drop', handleFileSelect, false);

</script>

</body>

</html>

View solution in original post

12 Replies
TracySchloss
Frequent Contributor

I don't believe ESRI licensing allows batch geocoding in this manner.  That is part of an ArcOnline subscription. 

0 Kudos
JeffJacobson
Regular Contributor

This document describes what you are allowed to do with free vs. paid ArcGIS Online Geocode services. If you are using your own geocoding services then, of course, this does not apply to you.

Another alternative is the MapQuest Open Geocoding API Web Service.

0 Kudos
TracySchloss
Frequent Contributor

It sounds like a bit of a gray area.  If you aren't keeping the results beyond the session, then are you meeting the definition of 'batch'?  For myself, I have used the geocoder just as a means for getting the map focused to a particular area.

It might be OK in this scenario, but of course the next request from the user could be 'now I want to keep what I'm seeing' which just crosses over to 'not OK' without use of a subscription.

0 Kudos
JeffJacobson
Regular Contributor

It looks like the free version only allows one address per request.

0 Kudos
JeffJacobson
Regular Contributor

Here's a CSV-Reader JavaScript library that will allow the web browser to read the CSV file and convert it into JavaScript objects or arrays.

0 Kudos
HeathAnderson
Occasional Contributor

I am not sure that I clearly defined my problem.  I have a Geocode service running on our GIS Server in addition to a model that uses that same Geocode Service but creates an output shapefile and CSV table with matched addresses.  I want my coworkers to be able to click a button browse to a CSV with "Name", "Address", "City", "State", and "ZIP" as the column headers, click ok and the Geocoder Service will run.  This is what i have found from the REST API help page

Syntax:

{ "records"  : [ { "attributes" : {"<OBJECTID>" : "<OID11>","<field1>" : "<value11>", "<field2>" : "<value12>", "<field3>" : "<value13>"} }, { "attributes" : {"<OBJECTID>" : "<OID21>","<field1>" : "<value21>", "<field2>" : "<value22>", "<field3>" : "<value23>"} } ] } 

Example 1:

{ "records": [ { "attributes": { "OBJECTID": 1, "STREET": "440 Arguello Blvd", "ZONE": "94118" } }, { "attributes": { "OBJECTID": 2, "STREET": "450 Arguello Blvd", "ZONE": "94118" } } ] }

Do I need to create an input type as file, assign it to variable and then pass in the variable as the input parameters?

0 Kudos
PaulCrickard1
Occasional Contributor II

This uses Leaflet.js and makes an AJAX call to your GIS Service on ArcServer. Just change the URL to the location of your service. You can drag the textfile to the map and it will put markers on the map. And change the map center coordinates so it is where you want to be. Mine is in Albuquerque. This uses Drag and Drop functionality in HTML5 so you need a new browser - just use chrome.

My address file looks like this:

7520 Corona Ave NE

600 2nd St NW

6200 Paseo Del-Norte

3805 Northern Blvd NE

3701 Constitution Ave NE

320 Yale Boulevard SE

6001 Lomas Blvd NE

My HTML File:

<html>

<head>

  <title></title>

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />

<style>

#map{

height: 100%;

width:100%;

}

</style>

</head>

<body>

<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>

<div id="map" ></div>

<script>

var map = L.map('map',

{

center: [35.10418, -106.62987],

zoom: 9

});

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);

  function handleFileSelect(evt) {

    evt.stopPropagation();

    evt.preventDefault();

    var files = evt.dataTransfer.files; // FileList object.

    var reader = new FileReader(); 

    reader.onload = function(event) {          

      

var temp=event.target.result;

var text=temp.replace( /\n/g, "," );

var c=text.split(",");

for(i=0;i<c.length;i++){

url1="http://YourDomain/ArcGIS/rest/services/AddressLocator/GeocodeServer/findAddressCandidates?Street=";

url2=String(c);

url3="&outFields=&outSR=4326&f=pjson";

url=url1.concat(url2,url3);

var xhReq = new XMLHttpRequest();

xhReq.open("GET", url, false);

xhReq.send(null);

var serverResponse = xhReq.responseText;

var d=JSON.parse(serverResponse);

if(typeof d.candidates[0] == 'undefined'){alert("error in address: "+url2);}

else{

L.marker([parseFloat(d.candidates[0].location.y),parseFloat(d.candidates[0].location.x)]).addTo(map).bindPopup(url2);

}

}

    }       

     var s = reader.readAsText(files[0],"UTF-8");

  }

  function handleDragOver(evt) {

    evt.stopPropagation();

    evt.preventDefault();

    evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.

  }

  // Setup the dnd listeners.

  var dropZone = document.getElementById('map');

  dropZone.addEventListener('dragover', handleDragOver, false);

  dropZone.addEventListener('drop', handleFileSelect, false);

</script>

</body>

</html>

View solution in original post

HeathAnderson
Occasional Contributor

Works great, thank you.

Took a while to figure out that you can't have <!DOCTYPE html> on your page.  You must either delete it or comment it out.  Does you know why this is?  The page still functions correctly on IE, Chrome, and Firefox.

0 Kudos
PaulCrickard1
Occasional Contributor II

Don't know why <!DOCTYPE html> doesn't work. It is supposed to sit above the <html> tag and tell the browser it is HTML 5.

Glad it works for you.

0 Kudos