title: Matrix transform: Converting SVG path coordinates to Leaflet coordinate system
body: <p>The short version: How can I add SVG paths to a Leaflet map in such a way that the paths will update when the map coordinates change (e.g. on zoom change or slide)?</p>
  
  <p>The long version: Hello, I have a topographic <a href="https://s3-us-west-2.amazonaws.com/gathering-a-building/2000_Cooper_Robertson_G_cutout1.tif" rel="nofollow noreferrer">image</a> that contains building outlines. After geo-rectifying the image I used Photoshop to convert the raster data to <a href="https://s3-us-west-2.amazonaws.com/gathering-a-building/2000_Cooper_Robertson_G_cutout1.svg" rel="nofollow noreferrer">SVG</a>. I know the geo-coordinates of the bounding box that describe the SVG perimeter, and know the internal coordinates of SVG path elements. I'm wondering the best way to now add the buildings described in the path elements of the SVG above to a Leaflet map.</p>
  
  <p>Here's a fiddle that shows the bounding box of the SVG image in red and the buildings in blue: <a href="http://jsfiddle.net/duhaime/4vL925Lj/" rel="nofollow noreferrer">http://jsfiddle.net/duhaime/4vL925Lj/</a> As you can see, the buildings are not yet properly oriented with respect to the bounding box.</p>
  
  <p>My initial plan to align the buildings was to use a one-time script to convert the path elements from the SVG coordinate system into lat, long coordinates, then draw the buildings on the map using the polyline function I used to draw the bounding box: </p>
  
  <pre><code>var polyline = L.polyline(
    [upperLeft, upperRight, lowerRight, lowerLeft, upperLeft], 
    {color: 'red', className: 'bounding-box', weight: 2}
  ).addTo(map); 
  </code></pre>
  
  <p>The trouble with this approach is that Leaflet polylines can't draw Bezier curves, which are present in the SVG path elements above. As a workaround, I thought I could use linear approximations for the Bezier curves, though this might become a decent amount of work. </p>
  
  <p>Eventually I realized the SVG for the bounding box in the fiddle above uses Bezier curves, which gave me the idea that I might instead use matrix transforms to transpose the coordinate space of the building SVGs into the Leaflet coordinate space. The fiddle above uses a sample matrix transform css rule to transform the building layer.</p>
  
  <p>Before going further down this rabbit hole, I wanted to ask: What do others think is the best way to add the paths that describe the buildings in the SVG above to the Leaflet map in the fiddle? I would be very grateful for any advice others can offer on this question!</p>
  
  <p><strong>PROGRESS:</strong> I decided to simplify this problem and figure out how to use a matrix transform to transform one div ("A") into the aspect ratio of another div ("B"). In doing so, I made a small <a href="https://gist.github.com/duhaime/6195b082ac5fd34a0112c7e7b391baf7" rel="nofollow noreferrer">Python script</a> that takes as input the input div A's pixel coordinates and the desired output div B's pixel coordinates. This script generates the transform matrix X such that AX=B. The script is documented internally and has an accompanying <a href="https://jsfiddle.net/duhaime/9444Lnjp/" rel="nofollow noreferrer">fiddle</a>. </p>
  
  <p>I also made a <a href="https://gist.github.com/duhaime/384b26d9665a65f67ce405c3ad43ff51" rel="nofollow noreferrer">gist</a> that derives the transform matrix to project points from the SVG space into proper lat, lng coords. Worst case scenario, I can partition the SVG path elements, take the dot product of each point with the transform matrix, and draw polylines with leaflet to plot the buildings. That will of lose the Bezier curves though...</p>