Monday, February 25, 2019

Traffic_Mapping_Fun

Traffic_Mapping_Fun

I am working on a little, crude, traffic mapping system for Nassau. (Anywhere really, but I am doing it for Nassau.)

It started out this way...

I developed a little android app that used its location, speed, time, etc. to build a fake URL that contains this information and then requests this fake URL from a web server that I have access to the logs for. Since this is a fake URL, it never gets back what it asks for but this is intended. The information I need is now in the logs.

I can then scan web server logs and look for lines that the app created. I have a script that puts these lines into a format that I want to parse for the web map.

I am making the web map using openlayers and openstreetmap stuff. Oh, javascript, jquery, and bootstrap too.

Not that I really know how to use this stuff fit a kick. My ignorance is vast.

So. This is the html page: wblogger.html
<pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"><code style="color:#000000;word-wrap:normal;"> &lt;!doctype html&gt;  
 &lt;html lang="en"&gt;  
  &lt;head&gt;  
   &lt;link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" type="text/css"&gt;  
   &lt;style&gt;  
    .map {  
     height: 400px;  
     width: 100%;  
    }  
    #map {  
      position: relative;  
    }  
    #popup {  
      padding-bottom: 45px;  
    }  
   &lt;/style&gt;  
   &lt;script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"&gt;&lt;/script&gt;  
   &lt;script type = "text/javascript" src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"&gt;&lt;/script&gt;  
   &lt;script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"&gt;&lt;/script&gt;  
   &lt;link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"&gt;  
   &lt;script type="text/javascript"&gt;  
        //  
      $( document ).ready(function() {  
        console.log( "ready!" );  
      });  
   &lt;/script&gt;  
   &lt;title&gt;OpenLayers example&lt;/title&gt;  
  &lt;/head&gt;  
  &lt;body&gt;  
   &lt;h2&gt;zotzBrothers Traffic Map&lt;/h2&gt;  
   &lt;div id="map" style="width:1200px;height:800px" class="map"&gt;&lt;/div&gt;  
        &lt;div id="popup"&gt;&lt;/div&gt;  
   &lt;script type="text/javascript"&gt;  
   window.carLocs = new Array();  
        $.get('systemlines.txt', function(data){  
       window.carLocs = data.split('\n');  
       //console.log(window.carLocs);  
        mymap();  
   });  
 function mymap(){  
   var vectorSource = new ol.source.Vector({  
    //create empty vector  
   });  
   //create the style  
   var iconStyle = new ol.style.Style({  
    image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({  
     anchor: [0, 0],  
     anchorXUnits: 'fraction',  
     anchorYUnits: 'pixels',  
     opacity: 0.75,  
      color: [113, 140, 0],  
     src: 'ol_icon.png'  
    }))  
   });  
   //create a bunch of icons and add to source vector  
   for (var i=0;i&lt;(carLocs.length-1);i++){  
      var myrecs = carLocs[i].split('/');  
           //console.log("lat ",mypos[0]," long ",mypos[1], " speed ", mypos[2]);  
           //console.log(myrecs[0],myrecs[1],myrecs[2],myrecs[3],myrecs[4],myrecs[5])  
       var mypos = myrecs[4].split('||');  
           //console.log("lat ",mypos[0]," long ",mypos[1], " speed ", mypos[2]);  
           //console.log(mypos);  
       var myspeed = myrecs[5].split(':');   
           //console.log("Only speed: ",myspeed[1]);  
       var dauser = myrecs[2];  
      //console.log("user ",dauser);       
      var dalat = Number(mypos[1]);  
      //console.log("lat ",dalat);  
      var dalong = Number(mypos[0]);  
      //console.log("long ",dalong);  
      //console.log("speed bit: ", myrecs[5]);  
      var daspeed = Math.round( Number(myspeed[1]) * 10 ) / 10;  
      //console.log("speed ",daspeed);  
      //console.log(dalat,dalong,daspeed);  
     var iconFeature = new ol.Feature({  
      geometry: new   
       ol.geom.Point(ol.proj.transform([dalat, dalong], 'EPSG:4326',  'EPSG:3857')),  
     name: 'daInstance_' + i + " Speed: " + daspeed,  
     speed: daspeed  
     });  
      if (daspeed &lt; 10) {  
           iconFeature.setStyle(new ol.style.Style({  
                image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({  
                     anchor: [0, 0],  
                         anchorXUnits: 'fraction',  
                         anchorYUnits: 'pixels',  
                         opacity: 0.75,  
                          color: '#DC143C',  
                         src: 'ol_icon.png',  
                          scale: 0.5  
                     }))  
                }));  
      }  
     vectorSource.addFeature(iconFeature);  
   }  
   //add the feature vector to the layer vector, and apply a style to whole layer  
   var vectorLayer = new ol.layer.Vector({  
    source: vectorSource,  
    style: iconStyle  
   });  
   var map = new ol.Map({  
    layers: [new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer],  
    target: document.getElementById('map'),  
    view: new ol.View({  
     center: ol.proj.fromLonLat([-77.353011, 25.0785398]),  
     zoom: 12  
    })  
   });  
   var element = document.getElementById('popup');  
   var popup = new ol.Overlay({  
      element: element,  
      positioning: 'bottom-center',  
      stopEvent: false  
   });  
   map.addOverlay(popup);  
 // display popup on click  
 map.on('click', function(evt) {  
  var feature = map.forEachFeatureAtPixel(evt.pixel,  
   function(feature, layer) {  
    return feature;  
   });  
  if (feature) {  
   var geometry = feature.getGeometry();  
   var coord = geometry.getCoordinates();  
   popup.setPosition(coord);  
   $(element).popover({  
    'placement': 'top',  
    'html': true  
   });  
   $(element).data("bs.popover").options.content= feature.get('name');  
   $(element).popover("show");  
   //document.getElementsByClassName("popover-content")[0].innerHTML = feature.get('name');   
   //$(element).popover('show');  
  } else {  
   $(element).popover('destroy');  
  }  
 });  
 // change mouse cursor when over marker  
 map.on('pointermove', function(e) {  
  if (e.dragging) {  
   $(element).popover('destroy');  
   return;  
  }  
  var pixel = map.getEventPixel(e.originalEvent);  
  var hit = map.hasFeatureAtPixel(pixel);  
  map.getTarget().style.cursor = hit ? 'pointer' : '';  
 });  
 }  
   &lt;/script&gt;  
  &lt;/body&gt;  
 &lt;/html&gt;  
</code></pre>


And this is the datafile: systemlines.txt
/zbloc/U999999/Speed_OK:13.93651/25.07857||-77.34838||-20.33905/Current_Speed:13.93651
/zbloc/U999999/Speed_OK:21.58705/25.07843||-77.35162||-27.1488/Current_Speed:21.58705
/zbloc/U999999/Speed_OK:29.55077/25.07976||-77.36289||-31.21094/Current_Speed:29.55077
/zbloc/U999999/Speed_OK:30.40083/25.07899||-77.35873||-31.58047/Current_Speed:30.40083
/zbloc/U999999/Speed_OK:31.63118/25.07833||-77.35521||-21.68082/Current_Speed:31.63118
/zbloc/U999999/Speed_OK:9.19407/25.0782||-77.34737||-31.22083/Current_Speed:9.19407
/zbloc/U999999/Speed_Slow:0/25.07853||-77.35114||-42.20892/Current_Speed:0
/zbloc/U999999/Speed_Slow:11.94558/25.07862||-77.34995||-18.98419/Current_Speed:11.94558
/zbloc/U999999/Speed_Slow:13.93651/25.07857||-77.34838||-20.33905/Current_Speed:13.93651
/zbloc/U999999/Speed_Slow:14.11547/25.07856||-77.34897||-27.05417/Current_Speed:14.11547
/zbloc/U999999/Speed_Slow:1.45405/25.07847||-77.35113||-20.47964/Current_Speed:1.45405
/zbloc/U999999/Speed_Slow:1.54353/25.07853||-77.35106||-30.974/Current_Speed:1.54353
/zbloc/U999999/Speed_Slow:1.54353/25.07853||-77.35106||-30.974/Current_Speed:1.54353
/zbloc/U999999/Speed_Slow:21.58705/25.07843||-77.35162||-27.1488/Current_Speed:21.58705
/zbloc/U999999/Speed_Slow:24.11486/25.07878||-77.35756||-29.90512/Current_Speed:24.11486
/zbloc/U999999/Speed_Slow:25.61365/25.07832||-77.35262||-30.26508/Current_Speed:25.61365
/zbloc/U999999/Speed_Slow:27.11244/25.07859||-77.35653||-33.70917/Current_Speed:27.11244
/zbloc/U999999/Speed_Slow:29.55077/25.07976||-77.36289||-31.21094/Current_Speed:29.55077
/zbloc/U999999/Speed_Slow:29.66262/25.07818||-77.35385||-27.67673/Current_Speed:29.66262
/zbloc/U999999/Speed_Slow:30.40083/25.07899||-77.35873||-31.58047/Current_Speed:30.40083
/zbloc/U999999/Speed_Slow:31.63118/25.07833||-77.35521||-21.68082/Current_Speed:31.63118
/zbloc/U999999/Speed_Slow:32.4365/25.07932||-77.36005||-27.33765/Current_Speed:32.4365
/zbloc/U999999/Speed_Slow:33.37604/25.07954||-77.3615||-28.73572/Current_Speed:33.37604
/zbloc/U999999/Speed_Slow:3.3555/25.07801||-77.34728||-24.91364/Current_Speed:3.3555
/zbloc/U999999/Speed_Slow:3.48972/25.07852||-77.34784||-7.2254/Current_Speed:3.48972
/zbloc/U999999/Speed_Slow:4.38452/25.07796||-77.34716||-26.48145/Current_Speed:4.38452
/zbloc/U999999/Speed_Slow:5.54776/25.07856||-77.35069||-15.47156/Current_Speed:5.54776
/zbloc/U999999/Speed_Slow:8.67956/25.07847||-77.3476||-11.89642/Current_Speed:8.67956
/zbloc/U999999/Speed_Slow:9.19407/25.0782||-77.34737||-31.22083/Current_Speed:9.19407

So this was my first take. What this shows...

  1. The ability to place "cars" on the map based on external data in a file.
  2. The ability to change the colour of the cars based on the car's speed.
  3. The ability to change the size of the cars. (Again based on the car's speed but this in not the final purpose for setting the size.)
  4. The ability to popup information about the car by clicking on its icon.
Desired improvements...
  1. Automatically put app data into a database. (mysql/mariadb with geo features.)
  2. Ability of web page to pull in data from the database instead of a text file.
  3. Ability to change the size of the car icons  in an intelligent way so that they scale with the size of the roads they are on as the map zoom changes.
  4. Fix the problem with the car icons being "offset" from the roads. Unless this turns out to be an issue with the data being inaccurate...
  5. (I don't think the problem mentioned in 4 can be the whole issue) Fix the fact that the car icon's position with respect to the map roads changes on zooming.
  6. It would be nice if the choice  of when to consider a car slow could be based on the speed limit of the road but that is not 100% necessary at this point.
  7. It would be nice to change the orientation of the car to match the road so that it does not sit sideways on north/south roads. (Perhaps it would be better to represent the car as a point if this is not possible?)
  8. perhaps add a few more colour coded speed "bands" rather than just red for slow and green for normal.
I have made progress on some of the above and will post improvements when I can.

I am looking for people who would like to discuss this and people who have a bit more expertise with openlayers/javascript/etc.

Friday, January 11, 2019

Augmented Reality Staging For Home Sales

Augmented Reality Staging For Home Sales

Consider AR staging for home sales... New home sales, renovations, flips...

Potential buyers show up. Put on the AR glasses/headgear and are led into the property.

They "see"' the place fully furnished and decorated. If they like it great. If not, they can discuss what they liked and did not like with the realtor/seller and they can be led into the property another time but this time see a completely different set up, furniture more to their liking, a colour scheme they prefer, different art work, a completely different "theme." Repeat as needed.

No need to rent furniture, art, and the rest and do an actual, physical staging of the property.

This could be tested against a Virtual Reality concept doing basically the same thing to see which performs better in which situations.

Wednesday, January 9, 2019

What If We Did Laws Like This

What If We Did Laws Like This?


----------------------------------------
Section 1.
Title/Name Of Law
----------------------------------------
Section 2.
Traditional Text of Law as we do now.
----------------------------------------
Section 3.
Spirit of this law is. ...
----------------------------------------
Section 4.
Intended to apply like this. Intended to be used for this.
----------------------------------------
Section 5.
Never to apply to this. Never to be used for this.
----------------------------------------
Section 6.
Intended consequences. Intended Results.
----------------------------------------
Section 7.
Guaranteed not to happen. Guaranteed not to result in this.
----------------------------------------
Section 8.
If sections 5 and  7 are violated, this entire law is null and void.
----------------------------------------


Friday, November 16, 2018

Fix For The Semi Recent Trump VS Acosta Drama

Fix For The Semi Recent Trump VS Acosta Drama

I was immediately struck by their sound system.

Technical fix:

Multiple wireless mics. (Say 3 or 4)
Each on a different channel on a mixer.
When your time is up, your channel is brought down.
Next person calls on gets a different mic and that channel is brought up.
If you know the order people will be called on, you can hand out the mics ahead of time and run things a bit smoother.

So, not need for a confrontation with someone who does not promptly give up the mic.

Now, it is a whole different matter as to whether such a fix would be in the best interests of the country or not.

Sunday, October 7, 2018

Crazy Political Ideas

Crazy Political Ideas

Bipartisan Influenced Term Limits

This idea came to me as a way to encourage bipartisan legislation. Basically, we set very short term limits for parliament/congress/the house/the senate. Then, we allow the term to be extended based on some ratio of bipartisan legislation passed and how *strong* a bipartisan effort it was.

Friday, September 14, 2018

New Lonely People

New Lonely People

Never before in the existence of the universe has a
Lonely heart found itself in such a state, seeking another
Person to touch, to connect, to sync with.
Breathe, breathe, breathe.
Sync, sync, sync.
Breathe.
Sink...
No comment.

Tuesday, July 24, 2018

Sports And Music In The Bahamas

Sports And Music In The Bahamas

Let's take sports and music as they exist in the Bahamas post high school. (This is from occasional personal observation and not from any systematic study.)

We have musicians who play in front of the public, or who would like to, complaining on a fairly regular basis that the financial rewards are too small and that they are not respected enough and etc. (I am not in any way saying that these points are completely invalid.)

We have athletes who also play in front of the public. Basketball, baseball, soccer, American football, cricket, and possibly others. As far as I know, none of these local athletes gets paid.

(We do have local athletes who go abroad and play professional sports to be sure.)

My guess is that local musicians earn more on average by "making" music than local athletes doing their thing. I don't recall local athletes complaining in the same way the musicians do. They seem to be playing for the love of the sport. I am sure some local musicians also play for the love of the music.

What is your take on this "situation" in your country?