using $.getJSON in a loop to append to global variable - javascript
I am writing a small script that takes an array of locations and geocodes them to add lat long to another object. I have it working so it geocodes and writes to the console flawlessly. How can I take that output and put it into a predefined variable outside of the function? I am not vary familiar with jquery and do not intend on using it anyplace else in the script.
Just started learning JavaScript this weekend so don't shoot me if Something else is messed up.
Thanks for any help!!
Also, I changed my Google API key so it isn't stolen.
//test array of locations to geocode
var locationsToGeoCode = ["China: Shandong: Jinan",
"China: Shandong: Jinan",
"United States: Washington: La Conner",
"United States: Texas: Dallas",
"United States: California: Walnut"
];
//empty object to place geocoded places
var coordinates;
for (var i = 0; i < locationsToGeoCode.length; i += 1) {
$.getJSON("https://maps.googleapis.com/maps/api/geocode/json?address=" + locationsToGeoCode[i] + "&key=MIzaSyCywKsD_50EI9rheDLyqPOUdUzi6s6u-q8", function (geocodeResult) {
console.log(geocodeResult);
});
}
Modifying your code like such should work:
//test array of locations to geocode
var locationsToGeoCode = ["China: Shandong: Jinan",
"China: Shandong: Jinan",
"United States: Washington: La Conner",
"United States: Texas: Dallas",
"United States: California: Walnut"
];
//empty object to place geocoded places
var coordinates = {};
function fetchGeoCode(location){
$.getJSON("https://maps.googleapis.com/maps/api/geocode/json?address=" + location + "&key=MIzaSyCywKsD_50EI9rheDLyqPOUdUzi6s6u-q8", function (geocodeResult) {
coordinates[location] = geocodeResult;
});
}
for (var i = 0; i < locationsToGeoCode.length; i += 1) {
fetchGeoCode(locationsToGeoCode[i]);
}
Related
Filtering GeoJSON data using array of values to create Leaflet map
I'm still new to coding so please forgive me if I'm not asking the right questions. I have a JSON file with data from a number of countries and I want to use Leaflet to paint all the countries in that file on a map. To do so I'm using a GeoJSON file containing all the countries of the world, and I want to filter this GeoJSON file by "id" (which is a 3-letter country code) so that it only includes the countries in my array (also 3-letter country code). I used D3.json to get an array of just the country codes from my JSON file, and then looped through that array to get each country in the list to filter my GeoJSON file: d3.json("countryList.json", function(data) { const countries = [...new Set(data.map(d => d.country))]; console.log(countries); for (var i = 0; i < countries.length; i++) { var countryCode = countries[i]; console.log(countryCode); }; I tried this with no luck: L.geoJson(data, { filter: function(feature) } if (feature.id === countryCode) return True } };
You don't need d3 to filter your countries. Also, when you initialize a variable inside a for-loop, it's going to get overwritten unless you break from the loop. Anyways, take this example of filtering a single U.S. state out of 2 states and go from there: var geojson_data = {"type":"FeatureCollection","features":[{"type":"Feature","id":"36","properties":{"name":"New York"},"geometry":{"type":"Polygon","coordinates":[[[-73.343806,45.013027],[-73.332852,44.804903],[-73.387622,44.618687],[-73.294514,44.437948],[-73.321898,44.246255],[-73.436914,44.043608],[-73.349283,43.769761],[-73.404052,43.687607],[-73.245221,43.523299],[-73.278083,42.833204],[-73.267129,42.745573],[-73.508114,42.08834],[-73.486206,42.050002],[-73.55193,41.294184],[-73.48073,41.21203],[-73.727192,41.102491],[-73.655992,40.987475],[-73.22879,40.905321],[-73.141159,40.965568],[-72.774204,40.965568],[-72.587988,40.998429],[-72.28128,41.157261],[-72.259372,41.042245],[-72.100541,40.992952],[-72.467496,40.845075],[-73.239744,40.625997],[-73.562884,40.582182],[-73.776484,40.593136],[-73.935316,40.543843],[-74.022947,40.708151],[-73.902454,40.998429],[-74.236547,41.14083],[-74.69661,41.359907],[-74.740426,41.431108],[-74.89378,41.436584],[-75.074519,41.60637],[-75.052611,41.754247],[-75.173104,41.869263],[-75.249781,41.863786],[-75.35932,42.000709],[-79.76278,42.000709],[-79.76278,42.252649],[-79.76278,42.269079],[-79.149363,42.55388],[-79.050778,42.690804],[-78.853608,42.783912],[-78.930285,42.953697],[-79.012439,42.986559],[-79.072686,43.260406],[-78.486653,43.375421],[-77.966344,43.369944],[-77.75822,43.34256],[-77.533665,43.233021],[-77.391265,43.276836],[-76.958587,43.271359],[-76.695693,43.34256],[-76.41637,43.523299],[-76.235631,43.528776],[-76.230154,43.802623],[-76.137046,43.961454],[-76.3616,44.070993],[-76.312308,44.196962],[-75.912491,44.366748],[-75.764614,44.514625],[-75.282643,44.848718],[-74.828057,45.018503],[-74.148916,44.991119],[-73.343806,45.013027]]]}},{"type":"Feature","id":"48","properties":{"name":"Texas"},"geometry":{"type":"Polygon","coordinates":[[[-101.812942,36.501861],[-100.000075,36.501861],[-100.000075,34.563024],[-99.923398,34.573978],[-99.698843,34.382285],[-99.57835,34.415147],[-99.260688,34.404193],[-99.189488,34.2125],[-98.986841,34.223454],[-98.767763,34.135823],[-98.570593,34.146777],[-98.488439,34.064623],[-98.36247,34.157731],[-98.170777,34.113915],[-98.088623,34.004376],[-97.946222,33.987946],[-97.869545,33.851022],[-97.694283,33.982469],[-97.458774,33.905791],[-97.371143,33.823637],[-97.256128,33.861976],[-97.173974,33.736006],[-96.922034,33.960561],[-96.850834,33.845545],[-96.631756,33.845545],[-96.423633,33.774345],[-96.346956,33.686714],[-96.149786,33.840068],[-95.936185,33.889361],[-95.8376,33.834591],[-95.602092,33.933176],[-95.547322,33.878407],[-95.289906,33.87293],[-95.224183,33.960561],[-94.966767,33.861976],[-94.868182,33.74696],[-94.484796,33.637421],[-94.380734,33.544313],[-94.183564,33.593606],[-94.041164,33.54979],[-94.041164,33.018527],[-94.041164,31.994339],[-93.822086,31.775262],[-93.816609,31.556184],[-93.542762,31.15089],[-93.526331,30.93729],[-93.630393,30.679874],[-93.728978,30.575812],[-93.696116,30.438888],[-93.767317,30.334826],[-93.690639,30.143133],[-93.926148,29.787132],[-93.838517,29.688547],[-94.002825,29.68307],[-94.523134,29.546147],[-94.70935,29.622824],[-94.742212,29.787132],[-94.873659,29.672117],[-94.966767,29.699501],[-95.016059,29.557101],[-94.911997,29.496854],[-94.895566,29.310638],[-95.081782,29.113469],[-95.383014,28.867006],[-95.985477,28.604113],[-96.045724,28.647929],[-96.226463,28.582205],[-96.23194,28.642452],[-96.478402,28.598636],[-96.593418,28.724606],[-96.664618,28.697221],[-96.401725,28.439805],[-96.593418,28.357651],[-96.774157,28.406943],[-96.801542,28.226204],[-97.026096,28.039988],[-97.256128,27.694941],[-97.404005,27.333463],[-97.513544,27.360848],[-97.540929,27.229401],[-97.425913,27.262263],[-97.480682,26.99937],[-97.557359,26.988416],[-97.562836,26.840538],[-97.469728,26.758384],[-97.442344,26.457153],[-97.332805,26.353091],[-97.30542,26.161398],[-97.217789,25.991613],[-97.524498,25.887551],[-97.650467,26.018997],[-97.885976,26.06829],[-98.198161,26.057336],[-98.466531,26.221644],[-98.669178,26.238075],[-98.822533,26.369522],[-99.030656,26.413337],[-99.173057,26.539307],[-99.266165,26.840538],[-99.446904,27.021277],[-99.424996,27.174632],[-99.50715,27.33894],[-99.479765,27.48134],[-99.605735,27.640172],[-99.709797,27.656603],[-99.879582,27.799003],[-99.934351,27.979742],[-100.082229,28.14405],[-100.29583,28.280974],[-100.399891,28.582205],[-100.498476,28.66436],[-100.629923,28.905345],[-100.673738,29.102515],[-100.799708,29.244915],[-101.013309,29.370885],[-101.062601,29.458516],[-101.259771,29.535193],[-101.413125,29.754271],[-101.851281,29.803563],[-102.114174,29.792609],[-102.338728,29.869286],[-102.388021,29.765225],[-102.629006,29.732363],[-102.809745,29.524239],[-102.919284,29.190146],[-102.97953,29.184669],[-103.116454,28.987499],[-103.280762,28.982022],[-103.527224,29.135376],[-104.146119,29.381839],[-104.266611,29.513285],[-104.507597,29.639255],[-104.677382,29.924056],[-104.688336,30.181472],[-104.858121,30.389596],[-104.896459,30.570335],[-105.005998,30.685351],[-105.394861,30.855136],[-105.602985,31.085167],[-105.77277,31.167321],[-105.953509,31.364491],[-106.205448,31.468553],[-106.38071,31.731446],[-106.528588,31.786216],[-106.643603,31.901231],[-106.616219,31.999816],[-103.067161,31.999816],[-103.067161,33.002096],[-103.045254,34.01533],[-103.039777,36.501861],[-103.001438,36.501861],[-101.812942,36.501861]]]}}]} L.geoJSON(geojson_data, { filter: function(feature) { return feature.properties.name === "Texas"; } }).addTo(map);
Two javascript arrays, using a key to look up
I have two data structures (they are much longer, these are just excerpts) var data = [ {count: 6, zip: "78705"}, {count: 4, zip: "78754"}, {count: 33, zip: "78757"} ] var txcodes = [ {county: "SWISHER", code: "437"}, {county: "TARRANT", code: "439"}, {county: "TAYLOR", code: "441"}, {county: "TRAVIS", code: "453"} ] I have written code that successfully goes through “data” and takes the zipcode and retrieves the corresponding county (from an external website via HTTP request). It returns a structure that looks like results = { TRAVIS: 8, TAYLOR: 1 } (8 and 1 are examples of counters for how many times a zipcode from data occurs…basically a running count). What I need to do next is use the keys from results to look up what the corresponding code in txcodes is. How do I do this? var currentCounty = str.result[0].County returns the county from results. console.log(txcodes[i].county + " " + txcodes[i].code) prints the county & code from txcodes. I’m a little confused on how to do this. It seems like a relatively simple concept but I can’t seem to get the desired result. Can someone please point me in the right direction?
If county names are unique and if you are going to be making repeated lookups, you should build a "map" of the codes out of the array: var txcodesByCounty = txcodes.reduce(function(p, c) { p[c.county] = c.code; return p; }, {}); You can then look up codes directly from this map.
Build a lookup map like this : var lookupMap = {}; for (var i = 0; i < txcodes.length; i++) { var element = txcodes[i]; lookupMap[element.county] = element; } Then you can simply do this to print the desired output : console.log(lookupMap[currentCounty].county + " " + lookupMap[currentCounty].code);
If the county in your result is only available as a key, you'll need to for..in, Object.keys or Object.getOwnPropertyNames to access them. After, access the details via a map as others have suggested var county, found = []; for (county in results) found.push(map[county]);
So what you get back from your HTTP request is a simple object, and you need to access its property names. You can do that easily with Object.keys: resultKeys = Object.keys(result); This will give you an array of the object properties: [ "TRAVIS", "TAYLOR" ] You can easily iterate over this array now, and inside you ask your result object for its value: for (var i = 0; i < resultKeys.length; i++) { console.log(resultkeys[i] + ": " + result[resultkeys[i]]); } Using this technique, you can use for example underscore.js libary to easily filter for your desired data: for (var i = 0; i < resultKeys.length; i++) { console.log(_.filter(txcodes , function(key){ return txcodes.county== resultkeys[i]; })); }
Adding Google Maps to project and retrive locatons from database using ASP.NET
what i mean i have xml file retrieve the database i want it as xml file and has fields i want to display it on Google map like 'city,country,street,longitude,latitude' i want take values from this fields and display it on google map.i want to display this map at page load event.the problem i can not know how retrieve the data from xml file and pass it to map . This is code behind, void GetTableFromXMlData(string strResult) { CreateTable(); XmlDataDocument xmlDataDoc = new XmlDataDocument(); xmlDataDoc.LoadXml(strResult); foreach (XmlNode n in xmlDataDoc.DocumentElement.GetElementsByTagName("Property")) { DataRow dr = dtSearchResult.NewRow(); dr["HotelID"] = n.Attributes["IDHotel"].Value; dr["HotelName"] = n.Attributes["Hotelname"].Value; dr["MinRate"] = n.Attributes["MinRate"].Value; dr["MaxRate"] = n.Attributes["MaxRate"].Value; dr["StarCategory"] = n.Attributes["StarCategory"].Value; dr["ImageIdentifier"] = n.Attributes["ImageIdentifier"].Value; dr["VPhotoPath"] = strVirtualPath + n.Attributes["ImageIdentifier"].Value + "_Exterior.jpg"; if (n.HasChildNodes) { foreach (XmlNode childNode in n) { switch (childNode.Name) { case "GEOData":///----->>>> here this the data i want to display it in a map. { dr["CountryCode"] = childNode.Attributes["CountryCode"].Value; dr["CityName"] = childNode.Attributes["City"].Value; dr["CityID"] = childNode.Attributes["IDCity"].Value; dr["Zip"] = childNode.Attributes["Zip"].Value; dr["Street"] = childNode.Attributes["Street"].Value; dr["Longitude"] = childNode.Attributes["Longitude"].Value; dr["Latitude"] = childNode.Attributes["Latitude"].Value; break; } case "Distances": { foreach (XmlNode cChildNode in childNode) { if (cChildNode.Attributes["Type"].Value == "1") dr["DistanceToCity"] = cChildNode.Attributes["Distance"].Value; else dr["DistanceToAirPort"] = cChildNode.Attributes["Distance"].Value; } break; } case "Descriptions": { dr["Descriptions"] = childNode.FirstChild.Attributes["Text"].Value; ((Label)FindControl("lblHoDescription1")).Text = childNode.FirstChild.Attributes["Text"].Value; break; } case "Meals": { dr["MinimumMeals"] = childNode.Attributes["MinimumMeals"].Value; break; } default: break; } } } dtSearchResult.Rows.Add(dr); } }
An example that goes from xml to maps
Once you have your data in XML format more than half of your work is done. What you need to do now is to play with Javascript a bit. You have to initialize the Google Maps using the function initialise(). Define the mapsize and type in MapOption. Create an instance of a Geocoder class & infoWindow class. Finally write the function to load markers where your markers are represented by a coordinate as a combination of Latitude and Longitude and the info window displaying the rest of the data like Street, Country Code, CityName, Zipcode. For detailed explanation you can take a look at the same tutorial larrp has posted.
Get definite City name in Google maps reverse geocoding
Using the Google Maps Geocoding API, i'm able to get the formatted address for a particular coordinate. To get the exact city name, I'm doing the following: $.ajax({ url: 'http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=false', success: function(data){ var formatted = data.results; var address_array = formatted[6].formatted_address.split(','); var city = address_array[0]; } }); where lat and long are derived using the browser coordinates. My problem is the following: From coordinates 19.2100 and 72.1800, I get the city as Mumbai, but from a similar set of coordinates about 3Km away, I get city as Mumbai Suburban. How can I get Mumbai without changing the success function of my code? It seems to me that the result array doesn't always stick to the same format which creates problems in my displaying of the city name.
So I was trying to figure this out today and I came to this solution if it helps anyone. Google maps comes with the Geocoder built in now so you just create a geocoder object once the API has loaded. You can easily wrap that in a function and just return an object with the city, state, and postal code. This site was helpful in allowing me to see what the different 'types' mean: Reverse Geocoding var geocoder = new google.maps.Geocoder, latitude = 28.54, //sub in your latitude longitude = -81.39, //sub in your longitude postal_code, city, state; geocoder.geocode({'location': {lat:latitude, lng:longitude}}, function(results, status) { if (status === google.maps.GeocoderStatus.OK) { results.forEach(function(element){ element.address_components.forEach(function(element2){ element2.types.forEach(function(element3){ switch(element3){ case 'postal_code': postal_code = element2.long_name; break; case 'administrative_area_level_1': state = element2.long_name; break; case 'locality': city = element2.long_name; break; } }) }); }); } });
You need to look at the type of the result, not the absolute index in the array of results. Iterate through the results array looking for the entry which has the appropriate type. Looks like that would be: locality indicates an incorporated city or town political entity But data may vary with region. related question: Grabbing country from google geocode jquery Looks like you want the entry with both the 'locality' and the 'political' types: { "long_name" : "Mumbai", "short_name" : "Mumbai", "types" : [ "locality", "political" ] }
For what it's worth, I was looking for something similar and am trying https://plus.codes/ If you strip the encoded bit it yields a fairly consistent city, state, country name: const extractCityName = latlng => { googleMapsClient.reverseGeocode({ latlng }, (err, response) => { if (!err) { return response.json.plus_code.compound_code.split(' ').slice(1).join(' '); } }); }; // examples: console.log(extractCityName(40.6599718,-73.9817292)); // New York, NY, USA console.log(extractCityName(37.386052, -122.083851)); // Mountain View, CA, USA console.log(extractCityName(51.507351, -0.127758)); // Westminster, London, UK
$.get({ url: locAPI, success: function(data) { data.results[0].address_components.forEach(function(element){ // console.log(element.types); if(element.types[0] == 'locality' && element.types[1] == 'political') { console.log('City:') console.log(element.long_name); } if(element.types[0] == 'country' && element.types[1] == 'political') { console.log('Country:') console.log(element.long_name); } }); } }) In My Case, I had to find City and Country Name.. That's what I did.
JSON to Array not working
I have a a JSON file with all my data in it and I want to read it to an array in my script.. below you can see an attempt, but it doesn't seem that "props" is actually getting data.. since I am new to javascript I am guessing there is something simple missing, hoping someone can tell me what I am doing wrong when loading the array. if I call alert(record) inside the loop it outputs "0", "1", "2" incrementing during each loop, if I try to alert(record.Address1) it returns "undefined", how does this work? var props = []; $.getJSON('http://someurl/auction.json', function(json) { for (var record in json) { props.push( record.Address1, record.City, record.State, record.Zip, record.Bed, record.Bath, record.Price, record.LotSize, record.SQFT, record.YearBuilt, "10%", record.latitude, record.longitude, record.Description ); } }); Here are the first couple records in the JSON file [ { "TrusteeNumber":"WA-14-611878-TC", "Date":"8/8/2014 8:00", "Address1":"7616 East Nora Avenue", "Address2":"", "County":"Spokane", "State":"WA", "Zip":99212, "Description":"Description for 7616 East Nora Avenue, Spokane Valley, Spokane, WA 99212\n\n\n\n\n \n Important Documents \n\n\nTrustee Sale Terms and Conditions \n\nSample Trustee Deed Upon Sale \n\nSample Certificate of Sale/Receipt \n\nIRS Form 8300", "City":"Spokane Valley", "AssetType":"Residential", "PropertyType":"SFR", "Beds":3, "Baths":1, "YearBuilt":1950, "SQFT":"1,160", "LotSize":0.25, "APN":"45073 0265", "EventItemNumber":"E2010-320", "PropertyID":1706957, "Image":"http://cdn.mlhdocs.com/rcp_files/auctions/E-2010/photos/thumbnails/155290117-1_bigThumb.jpg", "latitude":47.672913, "longitude":-117.301561 }, { "TrusteeNumber":"WA-14-611501-TC", "Date":"8/8/2014 8:00", "Address1":"235 W Columbia Ave", "Address2":"", "County":"Spokane", "State":"WA", "Zip":99205, "Description":"Description for 235 W Columbia Ave, Spokane, Spokane, WA 99205\n\n\n\n\n \n Important Documents \n\n\nTrustee Sale Terms and Conditions \n\nSample Trustee Deed Upon Sale \n\nSample Certificate of Sale/Receipt \n\nIRS Form 8300", "City":"Spokane", "AssetType":"Residential", "PropertyType":"SFR", "Beds":3, "Baths":3, "YearBuilt":1947, "SQFT":"3,151", "LotSize":0.15, "APN":"36311 3601", "EventItemNumber":"E2010-307", "PropertyID":1707641, "Image":"http://cdn.mlhdocs.com/rcp_files/auctions/E-2010/photos/thumbnails/208185496-1_bigThumb.jpg", "latitude":47.7107249, "longitude":-117.415536 }]
The loop you are using to iterate the json variable doesn't behave like foreach in other programming language. Instead it behave like ordinary for loop which will iterate through via index. So to use the json collection you need to modify your code like below: for (var record in json) { props.push( json[record].Address1, json[record].City, json[record].State, .... ); } Alternately you could try below as well and this will behave same like foreach in other programming language: $(json).each(function(index, record) { props.push( record.Address1, record.City, record.State, .... ); }); Hope this will help.
With for (var record in json), record isn't actually the record as is evident by the alerts of it, what it does is enumerate the property names in the object and since json is an array record is the indices of that array. If you want the records of the array you'll have to do json[record].Address1. I'd also suggest not using a for in loop for an array, the for (i = 0; i < json.length; i++) make it much more clear that you're looping an array
Your for loop isn't used correctly, in for( var record in json ), record is the index, which is in this case 0, 1 . to make it work try this: for (var key in json) { var record = json[key]; props.push( record.Address1, record.City, record.State, record.Zip, record.Bed, record.Bath, record.Price, record.LotSize, record.SQFT, record.YearBuilt, "10%", record.latitude, record.longitude, record.Description );
I have alerted the props variable in a few different places within the code and commented where it is null and where it has content. I have also added a comment on the line where I solved the problem. Basically call a function while props still has a value and assign that data to a global var from there. You cannot assign directly to the global without a function. <script type="text/javascript"> var props = [], returnData; function initialize() { $(document).ready(function() { $.ajax({ url: "http://5i2.us/jacksonmashup/allResults.json", async: false, dataType: 'json', success: function (data) { returnData = data; } }); var len = returnData.length; for (var i = 0; i < len; i++){ var record = returnData[i]; props.push([ '<img src="' + record.Type + '"/>', record.Address1, record.City, record.State, record.Zip, record.Beds, record.Baths, record.Price, record.SQFT, record.LotSize, '10%', record.latitude, record.longitude, record.Description, record.Image, record.Type] ) }; }); } </script>