Tasos
Tasos

Reputation: 5361

Polymer v1.0 iron-list distance calculation as each item is created on the list

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

enter image description here

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

Answers (1)

Tasos
Tasos

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

Related Questions