I need to create a map/array for auto complete from a JSON response and I am looking for the best, most efficient way to do it in Ruby and Rails 3. A portion of the response is below and the working code I have is before it. What is the one line of code I need to create locations for me?
# Need help making this more efficient
response_fields = JSON.parse(response.body)
predictions = response_fields['predictions']
predictions.each do |prediction|
locations << prediction['description']
end
Sample response from API:
{
"predictions" : [
{
"description" : "Napa, CA, United States",
"id" : "cf268f9fb9a1b46aed72d59ab85ed40f982763c6",
"matched_substrings" : [
{
"length" : 4,
"offset" : 0
}
],
"reference" : "CjQvAAAAqZWNGzqtJf3awNuQNQdnZpl4dBVVXFPrPdz29r1jo1GMWYFuz3KRlK9HgdgszOThEhDeYz_vYgcOPJTaYehF11bUGhR8yH9zqMGV9kenZIo9OTBrSwftgg",
"terms" : [
{
"offset" : 0,
"value" : "Napa"
},
{
"offset" : 6,
"value" : "CA"
},
{
"offset" : 10,
"value" : "United States"
}
],
"types" : [ "locality", "political", "geocode" ]
},
You can shorten your code like this:
locations = JSON.parse(response.body)['predictions'].map { |p| p['description'] }
Related
I have a gltf in which I apply png textures on rectangular mesh. I have a rectangle png and circle png. rectangle node is at z = 0.01 and circle at z = 0.0. alpha mode used for the materials is BLEND. material is double sided.
GLTF
{
"scenes" : [
{
"nodes" : [
0
]
}
],
"nodes" : [
{
"name" : "Node_0",
"children" : [
1,
3
]
},
{
"name" : "Symbol 2",
"children" : [
2
],
"translation" : [
240.25,
-126.300003,
0
]
},
{
"name" : "Node_2",
"mesh" : 0,
"scale" : [
0.656657,
0.656657,
1
]
},
{
"name" : "Symbol 1",
"children" : [
4
],
"translation" : [
170,
-89.050003,
0
]
},
{
"name" : "Node_4",
"mesh" : 1,
"translation" : [
0,
0,
-0.01
],
"scale" : [
2.059968,
1.399979,
1
]
}
],
"meshes" : [
{
"primitives" : [
{
"attributes" : {
"POSITION" : 1,
"TEXCOORD_0" : 2
},
"indices" : 0,
"material" : 0
}
]
},
{
"primitives" : [
{
"attributes" : {
"POSITION" : 1,
"TEXCOORD_0" : 2
},
"indices" : 0,
"material" : 1
}
]
}
],
"buffers" : [
{
"uri" : "data:application/octet-stream;base64,AQAAAAAAAAADAAAAAwAAAAIAAAABAAAAAAAAAAAAAIAAAAAAAAAAAAAAyMIAAAAAAADIQgAAyMIAAAAAAADIQgAAAIAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAAAAAAAAAq6oqPacaKD+nGig/AACAP6caKD+nGig/AACAPwAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAACAAACAPwAAAACrqio9AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAABAcEOamfzCAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIA/AAAAAKuqKj2G1gNAfzKzPwAAgD+G1gNAfzKzPwAAgD8AAAAAAAAAAAAAAIAK1yO8AAAAAAAAAAAAAAAAAAAAgAAAgD8AAAAAq6oqPQAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAACpDmhmywgAAAAAAAAAAAAAAAAAAAAAAAACAAACAPw==",
"byteLength" : 376
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 24,
"target" : 34963
},
{
"buffer" : 0,
"byteOffset" : 24,
"byteLength" : 48,
"target" : 34962
},
{
"buffer" : 0,
"byteOffset" : 72,
"byteLength" : 32,
"target" : 34962
}
],
"accessors" : [
{
"name" : "accessor_0",
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5125,
"count" : 6,
"type" : "SCALAR",
"max" : [
3
],
"min" : [
0
]
},
{
"name" : "accessor_1",
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 4,
"type" : "VEC3",
"max" : [
100,
0,
0
],
"min" : [
0,
-100,
0
]
},
{
"name" : "accessor_2",
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 4,
"type" : "VEC2",
"max" : [
1,
1
],
"min" : [
0,
0
]
}
],
"materials" : [
{
"pbrMetallicRoughness" : {
"baseColorTexture" : {
"index" : 0
}
},
"alphaMode" : "BLEND",
"doubleSided" : true
},
{
"pbrMetallicRoughness" : {
"baseColorTexture" : {
"index" : 1
}
},
"alphaMode" : "BLEND",
"doubleSided" : true
}
],
"samplers" : [
{
"magFilter" : 9729,
"minFilter" : 9987,
"wrapS" : 33071,
"wrapT" : 33071
}
],
"textures" : [
{
"sampler" : 0,
"source" : 0
},
{
"sampler" : 0,
"source" : 1
}
],
"images" : [
{
"uri" : "Image0.png"
},
{
"uri" : "Image1.png"
}
],
"asset" : {
"version" : "2.0"
}
}
PNGs
I am using ThreeJs gltf viewer. https://gltf-viewer.donmccurdy.com/
blending works fine at some angles but when i rotate around some angles blending does not work. screenshots
Can Someone explain this behaviour to me and how can i achieve correct blending at all angles.
If these are three separate nodes, and they all live at 0,0,0 you might have a sorting problem. GLTF is readable, but I'm not as familiar with the spec to tell what is going on. The nodes mentioned in the file that do not have a translation field, might all be positioned at 0,0,0
Either way, the remedy for something like this, if you want to keep sorting is to assign a different yourMesh.renderOrder = yourDesiredOrder. So for these elements you could set 1,2,3,4... and control when you want them to draw / tell the sorting to consider these weights.
This query works great, but it's returning too many results. I would like to add the boost function but I don't know the proper syntax.
$data_string = '{
"from" : 0, "size" : 100,
"sort" : [
{ "date" : {"order" : "desc"} }
],
"query": {
"more_like_this_field" : {
"thread.title" : {
"like_text" : "this is a test",
"min_word_len" : 4,
"min_term_freq" : 1,
"min_doc_freq" : 1
}
}
}
}';
Found the solution. Looks like using fuzzy_like_this_field and min_similarity is the way to go.
$data_string = '{
"from" : 0, "size" : 100,
"query": {
"fuzzy_like_this_field" : {
"thread.title" : {
"like_text" : "this is a test",
"min_similarity": 0.9
}
}
}
}';
According to the docs, you just need to add it to the other parameters:
...
"thread.title" : {
"like_text" : "this is a test",
"min_word_len" : 4,
"min_term_freq" : 1,
"min_doc_freq" : 1,
"boost": 1.0
}
...
Also, if you have too many docs, you can try to increase the min_term_freq and the min_doc_freq, too.
When I perform a Google Places Autocomplete request for "98 Spru" I get a Place prediction with one id (013ae3e513081ff1bc9e3dc202df54ba9d147285) and one set of types ("route" and "geocode") but when I fetch for the details of that Place it has a different id (5e66bbb5a5a7eaedd07fabc199e87570bcc0eae6) and a different set of types ("street_address")? The rest of the information is correct. Snippets of requests / responses below.
Is this expected and if so why?
On the client side I'm trying to filter out Autocomplete predictions that are not of some specific type (e.g. "street_address"). This doesn't work since the "types" field in the Autocomplete response doesn't consistently match the "true" types value as returned in the Details response.
Thanks!
Autocomplete Request / Response for "98 Spru"
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=98%20Spru&sensor=true&key=MYKEY&location=42.350000,-71.160000&radius=100.000000&types=geocode
{
"description" : "98 Spruce Street, Watertown, MA, United States",
"id" : "013ae3e513081ff1bc9e3dc202df54ba9d147285",
"matched_substrings" : [
{
"length" : 7,
"offset" : 0
}
],
"reference" : "CmRcAAAArJjcgqYuczq9wKmQG0lwv6j_uCBYCrWzS_U76FvnV3fCnWq0_pPf-nu6M9eTYQEpYt4XahA3Vg0GSzMcR23k3Mkxp9sv73ObGmeHDcanEnZ0dWpl69t7eSwmzLbrREQfEhA0CrWTEXtfQhcnfNWnqTukGhQFWBj_lPkoAwG-ZvUIv0GZhgAscQ",
"terms" : [
{
"offset" : 0,
"value" : "98 Spruce Street"
},
{
"offset" : 18,
"value" : "Watertown"
},
{
"offset" : 29,
"value" : "MA"
},
{
"offset" : 33,
"value" : "United States"
}
],
"types" : [ "route", "geocode" ]
},
Details Request / Response from above prediction:
https://maps.googleapis.com/maps/api/place/details/json?key=MYKEY&sensor=true&reference=CmRcAAAAzcupmv2dCaIWTnySJhA8y4BIc5_VSj1AUXCBFHEVnuo3NGjuqAVrLGSVZ_NODQstUs1ZclGASEzBYTF0B1nFSAcjgrc7Jn9NhJC2GZ2RtQQ3REFV7pvBzTPoGOHew289EhAD7dQFOe2EvBjpQ46IKODbGhTH0scvHs54U3refjf1-Tn6-04XvQ
{
"debug_info" : [],
"html_attributions" : [],
"result" : {
"address_components" : [
{
"long_name" : "98",
"short_name" : "98",
"types" : [ "street_number" ]
},
{
"long_name" : "Spruce St",
"short_name" : "Spruce St",
"types" : [ "route" ]
},
{
"long_name" : "Watertown",
"short_name" : "Watertown",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Middlesex",
"short_name" : "Middlesex",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Massachusetts",
"short_name" : "MA",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "02472",
"short_name" : "02472",
"types" : [ "postal_code" ]
}
],
"adr_address" : "\u003cspan class=\"street-address\"\u003e98 Spruce St\u003c/span\u003e, \u003cspan class=\"locality\"\u003eWatertown\u003c/span\u003e, \u003cspan class=\"region\"\u003eMA\u003c/span\u003e \u003cspan class=\"postal-code\"\u003e02472\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eUSA\u003c/span\u003e",
"formatted_address" : "98 Spruce St, Watertown, MA 02472, USA",
"geometry" : {
"location" : {
"lat" : 42.3667790,
"lng" : -71.1698590
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
"id" : "5e66bbb5a5a7eaedd07fabc199e87570bcc0eae6",
"name" : "98 Spruce St",
"reference" : "CpQBhgAAABX6gm9Qh9r9QxMuEWIrwFGcsz2QnUG0MAoEkD33kwrxfcEakZh-d01oWlAFnIieF8MvVcflI7xJ91Qq2ahnw9oDjcUPUnhlRcOUjLF0lTXOWf3Fp3dbCqLo3MQxCDGT3UJj5fR4ZrPagqBYXtQcPl1TB6sgPHZv8x-2jdJzbh-yZ6yb9VhfG-KDD76-RdotkRIQ7Oz0mKuwaclr0xiIf4oHehoUM2l9nZsi5pU2RPyB7YA2lmJ7vI0",
"types" : [ "street_address" ],
"url" : "https://maps.google.com/maps/place?q=98+Spruce+St&ftid=0x89e3781f4bba528d:0xa7ec6e9a6bde2e4f",
"vicinity" : "Watertown"
},
"status" : "OK"
}
You can't rely on the googleId thats returned by the autocomplete API. You need to use the reference, make an API call to Place Details API, then use that ID. I believe sometimes Google will consolidate their places database such that the reference will 'redirect' to a new place.
I have inserted 3 records in my ElasticSearch index as follows:
curl -XPOST 'http://127.0.0.1:9200/geoindex_test/STREET?pretty=1' -d '
{ "cityNames" : [ { "language" : "ENG",
"name" : "w bridgewater",
"raw_name" : "W BRIDGEWATER"
},
{ "language" : "ENG",
"name" : "west bridgewater",
"raw_name" : "West Bridgewater"
}
],
"id" : 1,
"streetNames" : [ { "language" : "ENG",
"name" : "cram rd",
"raw_name" : "Cram Rd"
} ]
}'
curl -XPOST 'http://127.0.0.1:9200/geoindex_test/STREET?pretty=1' -d '
{ "cityNames" : [ { "language" : "ENG",
"name" : "bridgewater corners",
"raw_name" : "BRIDGEWATER CORNERS"
},
{ "language" : "ENG",
"name" : "bridgewater center",
"raw_name" : "Bridgewater Center"
}
],
"id" : 2,
"streetNames" : [ { "language" : "ENG",
"name" : "valley view rd",
"raw_name" : "Valley View Rd"
} ]
}'
curl -XPOST 'http://127.0.0.1:9200/geoindex_test/STREET?pretty=1' -d '
{ "cityNames" : [ { "language" : "ENG",
"name" : "bridgewater",
"raw_name" : "Bridgewater"
},
{ "language" : "ENG",
"name" : "windsor",
"raw_name" : "Windsor"
}
],
"id" : 3,
"streetNames" : [ { "language" : "ENG",
"name" : "valley view rd",
"raw_name" : "Valley View Rd"
} ]
}'
And I perform a search as follows:
curl -XGET 'http://127.0.0.1:9200/geoindex_test/STREET/_search?pretty=1' -d '
{
"query" : {
"match" : { "cityNames.name" : "bridgewater" }
}
}'
I thought ElasticSearch would return the third record (id == 3) as the best match (record 3 is the only exact match to "bridgewater"), but instead it returns the record for id 1 (w bridgewater) as the best match. What am I doing wrong?
I imagine this is happening because you are using inner objects which basically collapse the objects under it, into one for search purposes. So when you're querying the search field for Object 1, for example, you're querying against ["w bridgewater", "west bridgewater"] and not discrete fields as you may imagine.
Since 'bridgewater' appears twice in object 1 and 2 (two name fields) vs once in object 3, those items rank higher in the search. Object 1 is ultimately picked, because the fields that 'bridgewater' appears in are shorter strings than in Object 2 ("w bridgewater" vs "bridgewater corners").
Instead of using inner objects like you're doing, use nested objects instead http://www.elasticsearch.org/guide/reference/mapping/nested-type/. setting the score mode to "max" will then make things match in a more intuitive manner for you.
Here is a query that I believe should produces hotel with the same name very closed to the reference point.
https://maps.googleapis.com/maps/api/place/textsearch/xml?key=_your_api_key_goes_in_here_&sensor=false&language=en&location=56.1995,-4.746&radius=30000&query=ARROCHAR
As yo can see the location is 56.1995,-4.746. This is a place in UK. The query if for a hotel named Arrochar. The hotel does exist. The result look like this :
{
"html_attributions" : [],
"results" : [
{
"formatted_address" : "Arrochar, Staten Island, NY, USA",
"geometry" : {
"location" : {
"lat" : 40.59234250,
"lng" : -74.07407289999999
},
"viewport" : {
"northeast" : {
"lat" : 40.60012790,
"lng" : -74.05918419999999
},
"southwest" : {
"lat" : 40.5779020,
"lng" : -74.08570610
}
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
"id" : "c7d9f74dca8676759bfe7ea168b8547cd6de3c5e",
"name" : "Arrochar",
"reference" : "CpQBiAAAAKYklx4_uV5ovlJP-x-fGr2VAqzhUCRQ2icNBXj2b5TkGZMqix3tL4xyTizwa0_UdZ5VDbI3psEagu0tTiFc2N6Awn2OJE4Oc3NXtXyaUlADLhJKwnZSuMFLFv85ia3AKiR9fFVWH96u6lEcC16foKMyFREY_KR6Z97QdShfiJCPYNlYZye49gsdU0UsIx3YbxIQa5LUZiMGZvW8sQHn_Cog-hoUr4bMXlYdo9Xae82ZRL-BEDSKRAw",
"types" : [ "neighborhood", "political" ]
}
],
"status" : "OK"
}
As one can see this place is in US and it is more than 5000 km away. Now, if one goes and modifies the query too look like this:
https://maps.googleapis.com/maps/api/place/textsearch/xml?key=_your_api_key_goes_in_here_&sensor=false&language=en&location=56.1995,-4.746&radius=30000&query=hotel+ARROCHAR
Then the correct result appear:
{
"formatted_address" : "Main Street, Arrochar, United Kingdom",
"geometry" : {
"location" : {
"lat" : 56.199560,
"lng" : -4.7459760
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/lodging-71.png",
"id" : "78d53766dfb2c3bb6008301b079423fffb78b801",
"name" : "Arrochar Hotel",
"reference" : "CnRtAAAAJPg2ABkegIT9Q12hABjfGezwGgHCc3ur1W761rhtkQq0n6Id-cgaLREU-g8Uo5Bnw4ovaAnqCrYm_fHEKjBHOrHK5dvcGpAndQVsl-zi_qZSZR6Sa5HvYZI4pA3ne3rNTl0m4TwuwmMM0nx2gSkxEBIQFqgW85GrUZI8SQFvohgMiBoU51C716M4m-ySUVECgT4BFZUYB50",
"types" : [ "lodging", "establishment" ]
}
So why is Places API text search acting like that? Note, the location parameter point to the exact place where the hotel is. Yet, I get something that is 5000 km away, unless I add the word 'hotel'.
Thanks
This is pretty old but just in case, I believe you should use nearbysearch instead of textsearch. (In your url)
Based on Google Places API documentation, your search has nothing to do with an specific location/distance.
Take into account that by using 'nearby search,' location and radius are required parameters. 'textsearch' just requires query and key.
Note: Radius might be required not to be included if using rankby=distance. Check the documentation for more details.
Good luck.