Reputation: 5361
My knowledge in polymer iron-list is pretty low at the moment and i was wondering what is the best method to calculate distance while getting the lat and lon co-ordinates from json data and calculate it for each item and insert the result.
In Jquery this is so simple eg
$.getJSON(getthis, function(data) {
$.each(data.items, function(i, value){
itemlat = value.lat;
itemlng = value.lng;
dist = distance(lat,lng,itemlat,itemlng);
$(".main-content").append("<paper-item>....<span class='dist'>"+dist+"</span></paper-item>");
});
});
I have the code to get the users device Geo-location and a function to calculate the distance from two Geo positions and from using the iron-list demo i managed to calculate distances but im sure its the wrong/long winded way of going about it.
Code
<body unresolved>
<template is="dom-bind">
<iron-ajax id="ajaxPost" url="the-url" last-response="{{data}}"></iron-ajax>
<paper-scroll-header-panel class="fit" condenses keep-condensed-header>
<paper-toolbar class="tall">
<paper-icon-button icon="arrow-back"></paper-icon-button>
<div class="flex"></div>
<paper-icon-button icon="search"></paper-icon-button>
<paper-icon-button icon="more-vert"></paper-icon-button>
<div class="bottom title">iron-list</div>
</paper-toolbar>
<iron-list items="[[data.items]]" as="item">
<template>
<div>
<div class="item">
<iron-image style="box-shadow: 0 0 5px rgba(0,0,0,0.50);background-color:gray;width:80px; height:80px;" sizing="cover" src="[[item.path]]" preload></iron-image>
<div class="pad">
<div class="primary">[[item.the_title]]</div>
<div class="secondary">[[item.info]]</div>
<div class="dist secondary dim"><span>[[item.lat]]</span>,<span>[[item.lng]]</span></div>
</div>
<iron-icon class="bookmark" icon$="[[iconForItem(item)]]"></iron-icon>
<iron-icon icon="more-vert"></iron-icon>
</div>
</div>
</template>
</iron-list>
</paper-scroll-header-panel>
</template>
<script>
var lat,lng;
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
}
}
function showPosition(position) {
lat = position.coords.latitude;
lng = position.coords.longitude;
}
function distance(lat1,lon1,lat2,lon2) {
var R = 6371; // km (change this constant to get miles)
var devlat = (lat2-lat1) * Math.PI / 180;
var dLon = (lon2-lon1) * Math.PI / 180;
var a = Math.sin(devlat/2) * Math.sin(devlat/2) +
Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
if (d>1) return Math.round(d)+" km";
else if (d<=1) return Math.round(d*1000)+" m";
return d;
}
function finddist() {
setTimeout(function(){
var items = document.getElementsByClassName("dist");
Array.prototype.forEach.call(items, function(elements, index) {
var text = elements.textContent
if(text.indexOf(',') > -1)
{
var array = text.split(',');
var thislat = array[0];
var thislng = array[1];
var dist = distance(lat,lng,thislat,thislng);
elements.innerHTML = dist;
}
});
}, 0);
}
document.querySelector('template[is=dom-bind]').iconForItem = function(item) {
finddist();
return item ? (item.integer < 10000 ? 'star-border' : 'star') : '';
};
document.addEventListener('paper-header-transform', function(event) {
var title = this.querySelector('.title');
var detail = event.detail;
var deltaHeight = detail.height - detail.condensedHeight;
var scale = Math.max(0.6, (deltaHeight - detail.y) / (deltaHeight / 0.4) + 0.6);
Polymer.Base.transform('scale(' + scale + ') translateZ(0)', title);
});
function findlocation() {
if(lat) {
clearInterval(getloc);
document.getElementById("ajaxPost").generateRequest();
}
else {
getLocation();
}
}
var getloc = setInterval(findlocation, 1000);
</script>
</body>
Result
The code above waits until the users Geolocation is available then instigates the iron-ajax with document.getElementById("ajaxPost").generateRequest();
prints out the iron-list items with the lat and lon from json data for each item in <div class="dist secondary dim"><span>[[item.lat]]</span>,<span>[[item.lng]]</span></div>
and while the star icon is printed for the item it runs finddist();
function to calculate the distance by grabbing the items co-ordinates from <div class="dist secondary dim"><span>[[item.lat]]</span>,<span>[[item.lng]]</span></div>
.
works ok, but i'm very sure this is by far the wrong way to do it.
This is the new code i'm using as i wanted to move the whole ajax,iron list routine in a dom-module
and would like some help to calculate the distance on the fly.
<body unresolved>
<paper-scroll-header-panel class="fit" condenses keep-condensed-header>
<paper-toolbar class="tall">
<paper-icon-button icon="arrow-back"></paper-icon-button>
<div class="flex"></div>
<paper-icon-button icon="search"></paper-icon-button>
<paper-icon-button icon="more-vert"></paper-icon-button>
<div class="bottom title">iron-list</div>
</paper-toolbar>
<my-request></my-request>
</paper-scroll-header-panel>
<dom-module id="my-request">
<style>
iron-list {
background-color: var(--paper-grey-200, #eee);
}
.item {
@apply(--layout-horizontal);
margin: 16px 16px 0 16px;
padding: 20px;
border-radius: 8px;
background-color: white;
border: 1px solid #ddd;
}
.pad {
padding: 0 16px;
@apply(--layout-flex);
@apply(--layout-vertical);
}
.primary {
font-size: 16px;
font-weight: bold;
}
.secondary {
font-size: 14px;
}
.dim {
color: gray;
position: absolute;
right: 70px;
bottom: 10px;
}
.bookmark {
position: absolute;
bottom: 10;
right: 37px;
color:#D3D3D3;
}
</style>
<template>
<iron-ajax auto id="ajaxPost" url="the-url" handle-as="json" last-response="{{data}}" on-response="handleResponse"></iron-ajax>
<iron-list items="{{data.items}}" as="item">
<template>
<div>
<div class="item">
<iron-image style="box-shadow: 0 0 5px rgba(0,0,0,0.50);background-color:gray;width:80px; height:80px;" sizing="cover" src="[[item.path]]" preload></iron-image>
<div class="pad" style="">
<div class="primary">{{item.the_title}}</div>
<div class="secondary">{{item.info}}</div>
<div class="dist secondary dim"><span>{{item.lat}}</span>,<span>{{item.lng}}</span></div>
</div>
<iron-icon class="bookmark" icon="star"></iron-icon>
<iron-icon icon="more-vert"></iron-icon>
</div>
</div>
</template>
</iron-list>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'my-request',
handleResponse: function() {
console.log('handleResponse');
}
});
})();
</script>
</body>
Thanks
Upvotes: 1
Views: 401
Reputation: 5361
Oh dear, is so simple
Thanks to @Ben Thomas for the link to Computed Binding documentation
<div class="dist secondary dim"><span>{{doThisOnce(item.lat,item.lng)}}</span>
...
Polymer({
is: 'my-request',
handleResponse: function () {
},
doThisOnce: function(lat,lng) {
console.log(lat+"=="+lng);
// calculate distance
// return result
}
});
Upvotes: 0