Let's Make a Map

with

Mapsense.js

Table of Contents

https://jhnklly.github.io/mapsense-d3


John Kelly
@jhnklly
john@mapsense.co
https://developer.mapsense.co/


(Amos, head of recruiting.)

Mapsense Data

  • Query, extract, and code with large public datasets,
    such as OpenStreetMap and US Demographics

  • Publish open data to the world

Mapsense.js

What are vector tiles?

Vector-y!

  • Not a static image/raster/bitmap
  • Vertices! Attributes!
  • Dynamic styling
  • Interaction
  • Animation
  • Scale-Independent
  • Vector : Raster
    • Illustrator + Excel : MS Paint
    • Fresh Ingredients : Frozen Dinner

Tile-y!

http://a.tile.openstreetmap.org/0/0/0.png

http://a.tile.openstreetmap.org/18/41928/101333.png

Times 70 billion.

Vectile Geek Stuff

  • topology
    • shared boundaries
    • smaller size
    • no gaps or overlaps when simplified

Vectile Geek Stuff

  • quantization: like "snap-to-grid" or "coordinate precision"
  • delta-encoded: relative coordinates
  • [-122.41729335339737, 37.764892437675975] to [-122.4172505736351, 37.764881835836164] to [-122.41727739572524, 37.76488395620424]
    [-122417293μ, 37764892μ] to [-43, 11] to [17, 21]
  • protobuf’d: binary
  • zip’d: quicker transfer

Paws 4 Questions

styler.mapsense.co Great for designers. (And kids & grandparents too!)

bit.ly/1HhATiO OpenStreetMap POI comparisons

SVG within SVG

Mapsense Context API

Gerrymandering Analysis

Olde Style

Hat tip to Gregor Aisch & Kartograph!

Under the Hood


{"type":"Topology","q":[4096,4096],"transform":{"scale":[2.6822090148960476E-6,2.119827344163744E-6],"translate":[-122.43164062500001,37.779398571318765]},"srid":"4326","objects":{"land":{"type":"GeometryCollection","geometries":[{"id":0,"properties":{"minz":0},"type":"MultiPolygon","arcs":[[[1432]]]}]},"landuse":{"type":"GeometryCollection","geometries":[{"id":4705353,"properties":{"minz":13,"sub_layer":"park","leisure":"park","name":"Jefferson Square"},"type":"Polygon","arcs":[[0]]},{"id":6721233,"properties":{"minz":13,"sub_layer":"park","leisure":"pitch"},"type":"Polygon","arcs":[[1]]},{"id":7380715,"properties":{"building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[2]]},{"id":7846397,"properties":{"name":"Cathedral of Saint Mary of the Assumption","building":"yes","minz":15,"sub_layer":"building","amenity":"place_of_worship"},"type":"Polygon","arcs":[[3,4,5,6,7]]},{"id":7915992,"properties":{"name":"Margaret S. Hayward Playground","minz":13,"sub_layer":"park","leisure":"park"},"type":"Polygon","arcs":[[8]]},{"id":8594947,"properties":{"building":"yes","minz":15,"sub_layer":"building","name":"State of California Building"},"type":"Polygon","arcs":[[9,1433,10,11,12],[13]]},{"id":8649879,"properties":{"building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[14],[15]]},{"id":8700533,"properties":{"name":"Kintetsu Mall","building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[16,17,18]]},{"id":9037911,"properties":{"name":"War Memorial Veterans Building","building":"yes","minz":15,"sub_layer":"building","amenity":"theatre"},"type":"Polygon","arcs":[[19,1434,20]]},{"id":9054515,"properties":{"name":"Cathedral Hill Plaza","building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[21]]},{"id":9098966,"properties":{"name":"Safeway 0995","minz":15,"sub_layer":"building","building":"retail"},"type":"Polygon","arcs":[[22,1435]]},{"id":9167882,"properties":{"minz":15,"sub_layer":"building","building":"apartments"},"type":"Polygon","arcs":[[23,1436]]},{"id":9371343,"properties":{"building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[24,1437,25]]},{"id":9820605,"properties":{"building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[26]]},{"id":10005073,"properties":{"building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[27,-7,28],[29],[30]]},{"id":10054102,"properties":{"building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[31]]},{"id":10068970,"properties":{"building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[32,33,34,35,36,37]]},{"id":10069784,"properties":{"name":"Miyako Mall","building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[38,39,40,41,42]]},{"id":10135953,"properties":{"name":"Kinokuniya Mall","building":"yes","minz":15,"sub_layer":"building"},"type":"Polygon","arcs":[[43,44,45,1438]]},{"id":10441598,"properties":{"name":"KRON
    

Under the Hood

Consume Vectiles

Produce Vectiles

Developer Resources

https://developer.mapsense.co/

Steal this code.

What We'll Make

End Slidetime. Begin Maptime!

Next:

  1. Make a basemap.
  2. Add custom data to our basemap.
  3. Change the symbolization to reflect data values.
  4. Empower the end-user to control the visualization.

Keys: developer.mapsense.co

Codes: http://bit.ly/vectortime

Fire up your text editors

1. HTML boilerplate + libraries

<!doctype html>
<html>
    <head>
        
        
        

        

        
    </head>
    <body>
        
    </body>
</html>
    

2. Add a Mapsense basemap


d3.select("body").append("div")
    .attr("id","myMap")
    .attr("style","height: 100%;");

var myKey = /* https://developer.mapsense.co/account/#signUp  */;

var map = mapsense.map("#myMap")
    .add(mapsense.basemap().apiKey(myKey));
    

Gimme the keys! developer.mapsense.co

3. Ta-Da!

Keys: developer.mapsense.co

Codes: http://bit.ly/vectortime

Ideatime!

  1. Put Null Island on the map?
  2. Make an SF 311 browser?
  3. Drag & drop .csv to map?
  4. Natural Earth countries painted with their flag?
  5. Others?

https://jhnklly.github.io/mapsense-d3



https://developer.mapsense.co/

@jhnklly
john@mapsense.co