mirror of
https://github.com/aljazceru/twentyone-world.github.io.git
synced 2025-12-18 20:04:20 +01:00
1105 lines
79 KiB
HTML
1105 lines
79 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
|
<title>map.py</title>
|
|
<link rel="stylesheet" href="pycco.css">
|
|
</head>
|
|
<body>
|
|
<div id="background"></div>
|
|
<div id='container'>
|
|
<div class='section'>
|
|
<div class='docs'><h1>map.py</h1></div>
|
|
</div>
|
|
<div class='clearall'>
|
|
<div class='section' id='section-0'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-0'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">maplayer</span> <span class="kn">import</span> <span class="n">MapLayer</span>
|
|
<span class="kn">from</span> <span class="nn">geometry.utils</span> <span class="kn">import</span> <span class="n">geom_to_bbox</span>
|
|
<span class="kn">from</span> <span class="nn">geometry</span> <span class="kn">import</span> <span class="n">BBox</span><span class="p">,</span> <span class="n">View</span>
|
|
<span class="kn">from</span> <span class="nn">shapely.geometry.base</span> <span class="kn">import</span> <span class="n">BaseGeometry</span>
|
|
<span class="kn">from</span> <span class="nn">shapely.geometry</span> <span class="kn">import</span> <span class="n">Polygon</span>
|
|
<span class="kn">from</span> <span class="nn">proj</span> <span class="kn">import</span> <span class="n">projections</span>
|
|
<span class="kn">from</span> <span class="nn">filter</span> <span class="kn">import</span> <span class="n">filter_record</span>
|
|
<span class="kn">from</span> <span class="nn">errors</span> <span class="kn">import</span> <span class="n">KartographError</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-1'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-1'>#</a>
|
|
</div>
|
|
<h2>Map</h2>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-2'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-2'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-3'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-3'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">me</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">layerCache</span><span class="p">,</span> <span class="n">format</span><span class="o">=</span><span class="s">'svg'</span><span class="p">,</span> <span class="n">src_encoding</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">options</span> <span class="o">=</span> <span class="n">options</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">format</span> <span class="o">=</span> <span class="n">format</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-4'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-4'>#</a>
|
|
</div>
|
|
<p>List and dictionary references to the map layers.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">layers</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">layersById</span> <span class="o">=</span> <span class="p">{}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-5'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-5'>#</a>
|
|
</div>
|
|
<p>We will cache the bounding geometry since we need it twice, eventually.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">_bounding_geometry_cache</span> <span class="o">=</span> <span class="bp">False</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">_unprojected_bounds</span> <span class="o">=</span> <span class="bp">None</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-6'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-6'>#</a>
|
|
</div>
|
|
<p>The <strong>source encoding</strong> will be used as first guess when Kartograph tries to decode
|
|
the meta data of shapefiles etc. We use Unicode as default source encoding.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="ow">not</span> <span class="n">src_encoding</span><span class="p">:</span>
|
|
<span class="n">src_encoding</span> <span class="o">=</span> <span class="s">'utf-8'</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">_source_encoding</span> <span class="o">=</span> <span class="n">src_encoding</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-7'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-7'>#</a>
|
|
</div>
|
|
<p>Construct <a href="maplayer.py">MapLayer</a> instances for every layer and store references
|
|
to the layers in a list and a dictionary.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">layer_cfg</span> <span class="ow">in</span> <span class="n">options</span><span class="p">[</span><span class="s">'layers'</span><span class="p">]:</span>
|
|
<span class="n">layer_id</span> <span class="o">=</span> <span class="n">layer_cfg</span><span class="p">[</span><span class="s">'id'</span><span class="p">]</span>
|
|
<span class="n">layer</span> <span class="o">=</span> <span class="n">MapLayer</span><span class="p">(</span><span class="n">layer_id</span><span class="p">,</span> <span class="n">layer_cfg</span><span class="p">,</span> <span class="n">me</span><span class="p">,</span> <span class="n">layerCache</span><span class="p">)</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">layers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">layer</span><span class="p">)</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">layersById</span><span class="p">[</span><span class="n">layer_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">layer</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-8'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-8'>#</a>
|
|
</div>
|
|
<p>Initialize the projection that will be used in this map. This sounds easier than
|
|
it is since we need to compute lot's of stuff here.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">proj</span> <span class="o">=</span> <span class="n">me</span><span class="o">.</span><span class="n">_init_projection</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-9'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-9'>#</a>
|
|
</div>
|
|
<p>Compute the bounding geometry for the map.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">bounds_poly</span> <span class="o">=</span> <span class="n">me</span><span class="o">.</span><span class="n">_init_bounds</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-10'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-10'>#</a>
|
|
</div>
|
|
<p>Set up the <a href="geometry/view.py">view</a> which will transform from projected coordinates
|
|
(e.g. in meters) to screen coordinates in our map output.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">view</span> <span class="o">=</span> <span class="n">me</span><span class="o">.</span><span class="n">_get_view</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-11'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-11'>#</a>
|
|
</div>
|
|
<p>Get the polygon (in fact it's a rectangle in most cases) that will be used
|
|
to clip away unneeded geometry unless <em>cfg['export']['crop-to-view']</em> is set to false.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">view_poly</span> <span class="o">=</span> <span class="n">me</span><span class="o">.</span><span class="n">_init_view_poly</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-12'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-12'>#</a>
|
|
</div>
|
|
<p>Load all features that could be visible in each layer. The feature geometries will
|
|
be projected and transformed to screen coordinates.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="n">me</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="n">layer</span><span class="o">.</span><span class="n">get_features</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-13'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-13'>#</a>
|
|
</div>
|
|
<p>In each layer we will join polygons.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">_join_features</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-14'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-14'>#</a>
|
|
</div>
|
|
<p>Eventually we crop geometries to the map bounding rectangle.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">options</span><span class="p">[</span><span class="s">'export'</span><span class="p">][</span><span class="s">'crop-to-view'</span><span class="p">]</span> <span class="ow">and</span> <span class="n">format</span> <span class="o">!=</span> <span class="s">'kml'</span><span class="p">:</span>
|
|
<span class="n">me</span><span class="o">.</span><span class="n">_crop_layers_to_view</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-15'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-15'>#</a>
|
|
</div>
|
|
<p>Here's where we apply the simplification to geometries.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">_simplify_layers</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-16'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-16'>#</a>
|
|
</div>
|
|
<p>Also we can crop layers to another layer, useful if we need to limit geological
|
|
geometries such as tree coverage to a political boundary of a country.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">_crop_layers</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-17'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-17'>#</a>
|
|
</div>
|
|
<p>Or subtract one layer from another (or more), for instance to cut out lakes
|
|
from political boundaries.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">me</span><span class="o">.</span><span class="n">_subtract_layers</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-18'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-18'>#</a>
|
|
</div>
|
|
<h3>Initializing the map projection</h3>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_init_projection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-19'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-19'>#</a>
|
|
</div>
|
|
<p>Some output formats don't need map projection at all, so
|
|
we just return the identity projection.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">format</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'kml'</span><span class="p">,</span> <span class="s">'json'</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">projections</span><span class="p">[</span><span class="s">'ll'</span><span class="p">]()</span> <span class="c"># use no projection for KML</span>
|
|
|
|
<span class="n">opts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-20'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-20'>#</a>
|
|
</div>
|
|
<p>If either <em>lat0</em> or <em>lon0</em> were set to "auto", we need to
|
|
compute a nice center of the projection and update the
|
|
projection configuration.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">autoLon</span> <span class="o">=</span> <span class="s">'lon0'</span> <span class="ow">in</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">]</span> <span class="ow">and</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="s">'lon0'</span><span class="p">]</span> <span class="o">==</span> <span class="s">'auto'</span>
|
|
<span class="n">autoLat</span> <span class="o">=</span> <span class="s">'lat0'</span> <span class="ow">in</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">]</span> <span class="ow">and</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="s">'lat0'</span><span class="p">]</span> <span class="o">==</span> <span class="s">'auto'</span>
|
|
<span class="k">if</span> <span class="n">autoLon</span> <span class="ow">or</span> <span class="n">autoLat</span><span class="p">:</span>
|
|
<span class="n">map_center</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__get_map_center</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">autoLon</span><span class="p">:</span>
|
|
<span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="s">'lon0'</span><span class="p">]</span> <span class="o">=</span> <span class="n">map_center</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">autoLat</span><span class="p">:</span>
|
|
<span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="s">'lat0'</span><span class="p">]</span> <span class="o">=</span> <span class="n">map_center</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-21'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-21'>#</a>
|
|
</div>
|
|
<p>Load the projection class, if the id is known.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="s">'id'</span><span class="p">]</span> <span class="ow">in</span> <span class="n">projections</span><span class="p">:</span>
|
|
<span class="n">projC</span> <span class="o">=</span> <span class="n">projections</span><span class="p">[</span><span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="s">'id'</span><span class="p">]]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">KartographError</span><span class="p">(</span><span class="s">'projection unknown </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="s">'id'</span><span class="p">])</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-22'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-22'>#</a>
|
|
</div>
|
|
<p>Populate a dictionary of projection properties that
|
|
will be passed to the projection constructor as keyword
|
|
arguments.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">p_opts</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">prop</span> <span class="ow">in</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">]:</span>
|
|
<span class="k">if</span> <span class="n">prop</span> <span class="o">!=</span> <span class="s">"id"</span><span class="p">:</span>
|
|
<span class="n">p_opts</span><span class="p">[</span><span class="n">prop</span><span class="p">]</span> <span class="o">=</span> <span class="n">opts</span><span class="p">[</span><span class="s">'proj'</span><span class="p">][</span><span class="n">prop</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">projC</span><span class="p">(</span><span class="o">**</span><span class="n">p_opts</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-23'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-23'>#</a>
|
|
</div>
|
|
<h3>Determining the projection center</h3>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">__get_map_center</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-24'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-24'>#</a>
|
|
</div>
|
|
<p>To find out where the map will be centered to we need to
|
|
know the geographical boundaries.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">opts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span>
|
|
<span class="n">mode</span> <span class="o">=</span> <span class="n">opts</span><span class="p">[</span><span class="s">'bounds'</span><span class="p">][</span><span class="s">'mode'</span><span class="p">]</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">opts</span><span class="p">[</span><span class="s">'bounds'</span><span class="p">][</span><span class="s">'data'</span><span class="p">]</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-25'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-25'>#</a>
|
|
</div>
|
|
<p>If the bound mode is set to <em>bbox</em> we simply
|
|
take the mean latitude and longitude as center.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s">'bbox'</span><span class="p">:</span>
|
|
<span class="n">lon0</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">-</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="n">lat0</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">-</span> <span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-26'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-26'>#</a>
|
|
</div>
|
|
<p>If the bound mode is set to <em>point</em> we average
|
|
over all latitude and longitude coordinates.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">elif</span> <span class="n">mode</span><span class="p">[:</span><span class="mi">5</span><span class="p">]</span> <span class="o">==</span> <span class="s">'point'</span><span class="p">:</span>
|
|
<span class="n">lon0</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">lat0</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">m</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="n">lon</span><span class="p">,</span> <span class="n">lat</span><span class="p">)</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
|
|
<span class="n">lon0</span> <span class="o">+=</span> <span class="n">m</span> <span class="o">*</span> <span class="n">lon</span>
|
|
<span class="n">lat0</span> <span class="o">+=</span> <span class="n">m</span> <span class="o">*</span> <span class="n">lat</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-27'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-27'>#</a>
|
|
</div>
|
|
<p>The computationally worst case is the bound mode
|
|
<em>polygon</em> since we need to load the shapefile geometry
|
|
to compute its center of mass. However, we need
|
|
to load it anyway and cache the bounding geometry,
|
|
so this comes at low extra cost.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">elif</span> <span class="n">mode</span><span class="p">[:</span><span class="mi">4</span><span class="p">]</span> <span class="o">==</span> <span class="s">'poly'</span><span class="p">:</span>
|
|
<span class="n">features</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_bounding_geometry</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">features</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">features</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">geom</span><span class="p">,</span> <span class="n">BaseGeometry</span><span class="p">):</span>
|
|
<span class="p">(</span><span class="n">lon0</span><span class="p">,</span> <span class="n">lat0</span><span class="p">)</span> <span class="o">=</span> <span class="n">features</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">geom</span><span class="o">.</span><span class="n">representative_point</span><span class="p">()</span><span class="o">.</span><span class="n">coords</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">lon0</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">lat0</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">print</span> <span class="s">"unrecognized bound mode"</span><span class="p">,</span> <span class="n">mode</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">lon0</span><span class="p">,</span> <span class="n">lat0</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-28'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-28'>#</a>
|
|
</div>
|
|
<h3>Compute the projected bounding box</h3>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_init_bounds</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-29'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-29'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">format</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'kml'</span><span class="p">,</span> <span class="s">'json'</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">None</span> <span class="c"># no bounds needed for KML</span>
|
|
|
|
<span class="kn">from</span> <span class="nn">geometry.utils</span> <span class="kn">import</span> <span class="n">bbox_to_polygon</span>
|
|
|
|
<span class="n">opts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span>
|
|
<span class="n">proj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">proj</span>
|
|
<span class="n">mode</span> <span class="o">=</span> <span class="n">opts</span><span class="p">[</span><span class="s">'bounds'</span><span class="p">][</span><span class="s">'mode'</span><span class="p">][:]</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">opts</span><span class="p">[</span><span class="s">'bounds'</span><span class="p">][</span><span class="s">'data'</span><span class="p">]</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-30'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-30'>#</a>
|
|
</div>
|
|
<p>If the bound mode is set to <em>bbox</em> we simply project
|
|
a rectangle in lat/lon coordinates.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">mode</span> <span class="o">==</span> <span class="s">"bbox"</span><span class="p">:</span> <span class="c"># catch special case bbox</span>
|
|
<span class="n">sea</span> <span class="o">=</span> <span class="n">proj</span><span class="o">.</span><span class="n">bounding_geometry</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">projected</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
|
|
<span class="n">sbbox</span> <span class="o">=</span> <span class="n">geom_to_bbox</span><span class="p">(</span><span class="n">sea</span><span class="p">)</span>
|
|
<span class="n">sbbox</span><span class="o">.</span><span class="n">inflate</span><span class="p">(</span><span class="n">sbbox</span><span class="o">.</span><span class="n">width</span> <span class="o">*</span> <span class="n">opts</span><span class="p">[</span><span class="s">'bounds'</span><span class="p">][</span><span class="s">'padding'</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="n">bbox_to_polygon</span><span class="p">(</span><span class="n">sbbox</span><span class="p">)</span>
|
|
|
|
<span class="n">bbox</span> <span class="o">=</span> <span class="n">BBox</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-31'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-31'>#</a>
|
|
</div>
|
|
<p>If the bound mode is set to <em>points</em> we project all
|
|
points and compute the bounding box.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">mode</span><span class="p">[:</span><span class="mi">5</span><span class="p">]</span> <span class="o">==</span> <span class="s">"point"</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">lon</span><span class="p">,</span> <span class="n">lat</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
|
|
<span class="n">pt</span> <span class="o">=</span> <span class="n">proj</span><span class="o">.</span><span class="n">project</span><span class="p">(</span><span class="n">lon</span><span class="p">,</span> <span class="n">lat</span><span class="p">)</span>
|
|
<span class="n">bbox</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">pt</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-32'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-32'>#</a>
|
|
</div>
|
|
<p>In bound mode <em>polygons</em>, which should correctly be
|
|
named gemetry, we compute the bounding boxes of every
|
|
geometry. We will also.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">mode</span><span class="p">[:</span><span class="mi">4</span><span class="p">]</span> <span class="o">==</span> <span class="s">"poly"</span><span class="p">:</span>
|
|
<span class="n">features</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_bounding_geometry</span><span class="p">()</span>
|
|
<span class="n">ubbox</span> <span class="o">=</span> <span class="n">BBox</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">features</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">feature</span> <span class="ow">in</span> <span class="n">features</span><span class="p">:</span>
|
|
<span class="n">ubbox</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">geom_to_bbox</span><span class="p">(</span><span class="n">feature</span><span class="o">.</span><span class="n">geometry</span><span class="p">))</span>
|
|
<span class="n">feature</span><span class="o">.</span><span class="n">project</span><span class="p">(</span><span class="n">proj</span><span class="p">)</span>
|
|
<span class="n">fbbox</span> <span class="o">=</span> <span class="n">geom_to_bbox</span><span class="p">(</span><span class="n">feature</span><span class="o">.</span><span class="n">geometry</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="s">"min-area"</span><span class="p">])</span>
|
|
<span class="n">bbox</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">fbbox</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-33'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-33'>#</a>
|
|
</div>
|
|
<p>Save the unprojected bounding box for later to
|
|
determine what features can be skipped.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">_unprojected_bounds</span> <span class="o">=</span> <span class="n">ubbox</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">KartographError</span><span class="p">(</span><span class="s">'no features found for calculating the map bounds'</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-34'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-34'>#</a>
|
|
</div>
|
|
<p>If we need some extra geometry around the map bounds, we inflate
|
|
the bbox according to the set <em>padding</em>.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">bbox</span><span class="o">.</span><span class="n">inflate</span><span class="p">(</span><span class="n">bbox</span><span class="o">.</span><span class="n">width</span> <span class="o">*</span> <span class="n">opts</span><span class="p">[</span><span class="s">'bounds'</span><span class="p">]</span> <span class="p">[</span><span class="s">'padding'</span><span class="p">])</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-35'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-35'>#</a>
|
|
</div>
|
|
<p>At the end we convert the bounding box to a Polygon because
|
|
we need it for clipping tasks.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">return</span> <span class="n">bbox_to_polygon</span><span class="p">(</span><span class="n">bbox</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-36'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-36'>#</a>
|
|
</div>
|
|
<h3>Get bounding geometry</h3>
|
|
<p>For bounds mode "<em>polygons</em>" this helper function
|
|
returns a list of all geometry that the map should
|
|
be cropped to.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_get_bounding_geometry</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-37'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-37'>#</a>
|
|
</div>
|
|
<p>Use the cached geometry, if available.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bounding_geometry_cache</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bounding_geometry_cache</span>
|
|
|
|
<span class="n">opts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span>
|
|
<span class="n">features</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">opts</span><span class="p">[</span><span class="s">'bounds'</span><span class="p">][</span><span class="s">'data'</span><span class="p">]</span>
|
|
<span class="nb">id</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s">'layer'</span><span class="p">]</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-38'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-38'>#</a>
|
|
</div>
|
|
<p>Check that the layer exists.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="nb">id</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layersById</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">KartographError</span><span class="p">(</span><span class="s">'layer not found "</span><span class="si">%s</span><span class="s">"'</span> <span class="o">%</span> <span class="nb">id</span><span class="p">)</span>
|
|
<span class="n">layer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">layersById</span><span class="p">[</span><span class="nb">id</span><span class="p">]</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-39'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-39'>#</a>
|
|
</div>
|
|
<p>Construct the filter function of the layer, which specifies
|
|
what features should be excluded from the map completely.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'filter'</span><span class="p">]</span> <span class="ow">is</span> <span class="bp">False</span><span class="p">:</span>
|
|
<span class="n">layerFilter</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">a</span><span class="p">:</span> <span class="bp">True</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">layerFilter</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">rec</span><span class="p">:</span> <span class="n">filter_record</span><span class="p">(</span><span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'filter'</span><span class="p">],</span> <span class="n">rec</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-40'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-40'>#</a>
|
|
</div>
|
|
<p>Construct the filter function of the boundary, which specifies
|
|
what features should be excluded from the boundary calculation.
|
|
For instance, you often want to exclude Alaska and Hawaii from
|
|
the boundary computation of the map, although a part of Alaska
|
|
might be visible in the resulting map.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s">'filter'</span><span class="p">]:</span>
|
|
<span class="n">boundsFilter</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">rec</span><span class="p">:</span> <span class="n">filter_record</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s">'filter'</span><span class="p">],</span> <span class="n">rec</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">boundsFilter</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">a</span><span class="p">:</span> <span class="bp">True</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-41'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-41'>#</a>
|
|
</div>
|
|
<p>Combine both filters to a single function.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="nb">filter</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">rec</span><span class="p">:</span> <span class="n">layerFilter</span><span class="p">(</span><span class="n">rec</span><span class="p">)</span> <span class="ow">and</span> <span class="n">boundsFilter</span><span class="p">(</span><span class="n">rec</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-42'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-42'>#</a>
|
|
</div>
|
|
<p>Load the features from the layer source (e.g. a shapefile).</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">features</span> <span class="o">=</span> <span class="n">layer</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">get_features</span><span class="p">(</span>
|
|
<span class="nb">filter</span><span class="o">=</span><span class="nb">filter</span><span class="p">,</span>
|
|
<span class="n">min_area</span><span class="o">=</span><span class="n">data</span><span class="p">[</span><span class="s">"min-area"</span><span class="p">],</span>
|
|
<span class="n">charset</span><span class="o">=</span><span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'charset'</span><span class="p">]</span>
|
|
<span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-43'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-43'>#</a>
|
|
</div>
|
|
<p>Omit tiny islands, if needed.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'filter-islands'</span><span class="p">]:</span>
|
|
<span class="n">features</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">features</span>
|
|
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">geometry</span><span class="o">.</span><span class="n">area</span> <span class="o">></span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'filter-islands'</span><span class="p">]]</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-44'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-44'>#</a>
|
|
</div>
|
|
<p>Store computed boundary in cache.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="bp">self</span><span class="o">.</span><span class="n">_bounding_geometry_cache</span> <span class="o">=</span> <span class="n">features</span>
|
|
<span class="k">return</span> <span class="n">features</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-45'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-45'>#</a>
|
|
</div>
|
|
<p>returns the output view</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_get_view</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-46'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-46'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">format</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'kml'</span><span class="p">,</span> <span class="s">'json'</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">View</span><span class="p">()</span> <span class="c"># no view transformation needed for KML</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">src_bbox</span> <span class="o">=</span> <span class="n">bbox</span> <span class="o">=</span> <span class="n">geom_to_bbox</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bounds_poly</span><span class="p">)</span>
|
|
<span class="n">opts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span>
|
|
<span class="n">exp</span> <span class="o">=</span> <span class="n">opts</span><span class="p">[</span><span class="s">"export"</span><span class="p">]</span>
|
|
<span class="n">w</span> <span class="o">=</span> <span class="n">exp</span><span class="p">[</span><span class="s">"width"</span><span class="p">]</span>
|
|
<span class="n">h</span> <span class="o">=</span> <span class="n">exp</span><span class="p">[</span><span class="s">"height"</span><span class="p">]</span>
|
|
<span class="n">ratio</span> <span class="o">=</span> <span class="n">exp</span><span class="p">[</span><span class="s">"ratio"</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">ratio</span> <span class="o">==</span> <span class="s">"auto"</span><span class="p">:</span>
|
|
<span class="n">ratio</span> <span class="o">=</span> <span class="n">bbox</span><span class="o">.</span><span class="n">width</span> <span class="o">/</span> <span class="nb">float</span><span class="p">(</span><span class="n">bbox</span><span class="o">.</span><span class="n">height</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">h</span> <span class="o">==</span> <span class="s">"auto"</span><span class="p">:</span>
|
|
<span class="n">h</span> <span class="o">=</span> <span class="n">w</span> <span class="o">/</span> <span class="n">ratio</span>
|
|
<span class="k">elif</span> <span class="n">w</span> <span class="o">==</span> <span class="s">"auto"</span><span class="p">:</span>
|
|
<span class="n">w</span> <span class="o">=</span> <span class="n">h</span> <span class="o">*</span> <span class="n">ratio</span>
|
|
<span class="k">return</span> <span class="n">View</span><span class="p">(</span><span class="n">bbox</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span> <span class="n">h</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-47'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-47'>#</a>
|
|
</div>
|
|
<p>creates a polygon that represents the rectangular view bounds
|
|
used for cropping the geometries to not overlap the view</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_init_view_poly</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-48'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-48'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">format</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'kml'</span><span class="p">,</span> <span class="s">'json'</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">None</span> <span class="c"># no view polygon needed for KML</span>
|
|
<span class="n">w</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">width</span>
|
|
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">height</span>
|
|
<span class="k">return</span> <span class="n">Polygon</span><span class="p">([(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">h</span><span class="p">),</span> <span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="n">h</span><span class="p">),</span> <span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="mi">0</span><span class="p">)])</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-49'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-49'>#</a>
|
|
</div>
|
|
<p>performs polygon simplification</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_simplify_layers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-50'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-50'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="kn">from</span> <span class="nn">simplify</span> <span class="kn">import</span> <span class="n">create_point_store</span><span class="p">,</span> <span class="n">simplify_lines</span>
|
|
|
|
<span class="n">point_store</span> <span class="o">=</span> <span class="n">create_point_store</span><span class="p">()</span> <span class="c"># create a new empty point store</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-51'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-51'>#</a>
|
|
</div>
|
|
<p>compute topology for all layers</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'simplify'</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">False</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">feature</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="n">feature</span><span class="o">.</span><span class="n">compute_topology</span><span class="p">(</span><span class="n">point_store</span><span class="p">,</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'unify-precision'</span><span class="p">])</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-52'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-52'>#</a>
|
|
</div>
|
|
<p>break features into lines</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'simplify'</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">False</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">feature</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="n">feature</span><span class="o">.</span><span class="n">break_into_lines</span><span class="p">()</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-53'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-53'>#</a>
|
|
</div>
|
|
<p>simplify lines</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">total</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">kept</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'simplify'</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">False</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">feature</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">feature</span><span class="o">.</span><span class="n">break_into_lines</span><span class="p">()</span>
|
|
<span class="n">lines</span> <span class="o">=</span> <span class="n">simplify_lines</span><span class="p">(</span><span class="n">lines</span><span class="p">,</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'simplify'</span><span class="p">][</span><span class="s">'method'</span><span class="p">],</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'simplify'</span><span class="p">][</span><span class="s">'tolerance'</span><span class="p">])</span>
|
|
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
|
|
<span class="n">total</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">pt</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">pt</span><span class="o">.</span><span class="n">deleted</span><span class="p">:</span>
|
|
<span class="n">kept</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
<span class="n">feature</span><span class="o">.</span><span class="n">restore_geometry</span><span class="p">(</span><span class="n">lines</span><span class="p">,</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'filter-islands'</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="n">total</span><span class="p">,</span> <span class="n">kept</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-54'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-54'>#</a>
|
|
</div>
|
|
<p>cuts the layer features to the map view</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_crop_layers_to_view</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-55'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-55'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-56'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-56'>#</a>
|
|
</div>
|
|
<p>out = []</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">feat</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">feat</span><span class="o">.</span><span class="n">geometry</span><span class="o">.</span><span class="n">is_valid</span><span class="p">:</span>
|
|
<span class="k">pass</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-57'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-57'>#</a>
|
|
</div>
|
|
<p>print feat.geometry
|
|
_plot_geometry(feat.geometry)</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">feat</span><span class="o">.</span><span class="n">crop_to</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">view_poly</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-58'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-58'>#</a>
|
|
</div>
|
|
<p>if not feat.is_empty():
|
|
out.append(feat)
|
|
layer.features = out</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-59'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-59'>#</a>
|
|
</div>
|
|
<p>handles crop-to</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_crop_layers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-60'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-60'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'crop-to'</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">False</span><span class="p">:</span>
|
|
<span class="n">cropped_features</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">tocrop</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="n">cbbox</span> <span class="o">=</span> <span class="n">geom_to_bbox</span><span class="p">(</span><span class="n">tocrop</span><span class="o">.</span><span class="n">geom</span><span class="p">)</span>
|
|
<span class="n">crop_at_layer</span> <span class="o">=</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'crop-to'</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">crop_at_layer</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">KartographError</span><span class="p">(</span><span class="s">'you want to substract '</span>
|
|
<span class="o">+</span> <span class="s">'from layer "</span><span class="si">%s</span><span class="s">" which cannot be found'</span>
|
|
<span class="o">%</span> <span class="n">crop_at_layer</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">crop_at</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layersById</span><span class="p">[</span><span class="n">crop_at_layer</span><span class="p">]</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">crop_at</span><span class="o">.</span><span class="n">geom</span><span class="o">.</span><span class="n">bbox</span><span class="p">()</span><span class="o">.</span><span class="n">intersects</span><span class="p">(</span><span class="n">cbbox</span><span class="p">):</span>
|
|
<span class="n">tocrop</span><span class="o">.</span><span class="n">crop_to</span><span class="p">(</span><span class="n">crop_at</span><span class="o">.</span><span class="n">geom</span><span class="p">)</span>
|
|
<span class="n">cropped_features</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tocrop</span><span class="p">)</span>
|
|
<span class="n">layer</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="n">cropped_features</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-61'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-61'>#</a>
|
|
</div>
|
|
<h3>Subtract geometry</h3>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_subtract_layers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-62'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-62'>#</a>
|
|
</div>
|
|
<p>Substract geometry of a layer from the geometry
|
|
of one or more different layers. Added mainly
|
|
for excluding great lakes from country polygons.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'subtract-from'</span><span class="p">]:</span>
|
|
<span class="k">for</span> <span class="n">feat</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">feat</span><span class="o">.</span><span class="n">geom</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">cbbox</span> <span class="o">=</span> <span class="n">geom_to_bbox</span><span class="p">(</span><span class="n">feat</span><span class="o">.</span><span class="n">geom</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-63'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-63'>#</a>
|
|
</div>
|
|
<p>We remove it from multiple layers, if wanted.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">subid</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'subtract-from'</span><span class="p">]:</span>
|
|
<span class="k">if</span> <span class="n">subid</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layersById</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">KartographError</span><span class="p">(</span><span class="s">'you want to subtract'</span>
|
|
<span class="o">+</span> <span class="s">' from layer "</span><span class="si">%s</span><span class="s">" which cannot be found'</span>
|
|
<span class="o">%</span> <span class="n">subid</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layersById</span><span class="p">[</span><span class="n">subid</span><span class="p">]</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">s</span><span class="o">.</span><span class="n">geom</span> <span class="ow">and</span> <span class="n">geom_to_bbox</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">geom</span><span class="p">)</span><span class="o">.</span><span class="n">intersects</span><span class="p">(</span><span class="n">cbbox</span><span class="p">):</span>
|
|
<span class="n">s</span><span class="o">.</span><span class="n">subtract_geom</span><span class="p">(</span><span class="n">feat</span><span class="o">.</span><span class="n">geom</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-64'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-64'>#</a>
|
|
</div>
|
|
<p>Finally, we don't want the subtracted features
|
|
to be included in our map.</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">layer</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="p">[]</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-65'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-65'>#</a>
|
|
</div>
|
|
<h3>Joins features within a layer.</h3>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">_join_features</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-66'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-66'>#</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="kn">from</span> <span class="nn">geometry.utils</span> <span class="kn">import</span> <span class="n">join_features</span>
|
|
|
|
<span class="k">for</span> <span class="n">layer</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">layers</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'join'</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">False</span><span class="p">:</span>
|
|
<span class="n">unjoined</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">join</span> <span class="o">=</span> <span class="n">layer</span><span class="o">.</span><span class="n">options</span><span class="p">[</span><span class="s">'join'</span><span class="p">]</span>
|
|
<span class="n">groupBy</span> <span class="o">=</span> <span class="n">join</span><span class="p">[</span><span class="s">'group-by'</span><span class="p">]</span>
|
|
<span class="n">groups</span> <span class="o">=</span> <span class="n">join</span><span class="p">[</span><span class="s">'groups'</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">groups</span><span class="p">:</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-67'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-67'>#</a>
|
|
</div>
|
|
<p>auto populate groups</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="n">groups</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">feat</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="n">fid</span> <span class="o">=</span> <span class="n">feat</span><span class="o">.</span><span class="n">props</span><span class="p">[</span><span class="n">groupBy</span><span class="p">]</span>
|
|
<span class="n">groups</span><span class="p">[</span><span class="n">fid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">fid</span><span class="p">]</span>
|
|
|
|
<span class="n">groupAs</span> <span class="o">=</span> <span class="n">join</span><span class="p">[</span><span class="s">'group-as'</span><span class="p">]</span>
|
|
<span class="n">groupFeatures</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">feat</span> <span class="ow">in</span> <span class="n">layer</span><span class="o">.</span><span class="n">features</span><span class="p">:</span>
|
|
<span class="n">found_in_group</span> <span class="o">=</span> <span class="bp">False</span>
|
|
<span class="k">for</span> <span class="n">g_id</span> <span class="ow">in</span> <span class="n">groups</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">g_id</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">groupFeatures</span><span class="p">:</span>
|
|
<span class="n">groupFeatures</span><span class="p">[</span><span class="n">g_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">feat</span><span class="o">.</span><span class="n">props</span><span class="p">[</span><span class="n">groupBy</span><span class="p">]</span> <span class="ow">in</span> <span class="n">groups</span><span class="p">[</span><span class="n">g_id</span><span class="p">]</span> <span class="ow">or</span> <span class="nb">str</span><span class="p">(</span><span class="n">feat</span><span class="o">.</span><span class="n">props</span><span class="p">[</span><span class="n">groupBy</span><span class="p">])</span> <span class="ow">in</span> <span class="n">groups</span><span class="p">[</span><span class="n">g_id</span><span class="p">]:</span>
|
|
<span class="n">groupFeatures</span><span class="p">[</span><span class="n">g_id</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">feat</span><span class="p">)</span>
|
|
<span class="n">found_in_group</span> <span class="o">=</span> <span class="bp">True</span>
|
|
<span class="k">break</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">found_in_group</span><span class="p">:</span>
|
|
<span class="n">unjoined</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
<span class="n">res</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">feat</span><span class="p">)</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
<div class='section' id='section-68'>
|
|
<div class='docs'>
|
|
<div class='octowrap'>
|
|
<a class='octothorpe' href='#section-68'>#</a>
|
|
</div>
|
|
<p>print unjoined,'features were not joined'</p>
|
|
</div>
|
|
<div class='code'>
|
|
<div class="highlight"><pre> <span class="k">for</span> <span class="n">g_id</span> <span class="ow">in</span> <span class="n">groups</span><span class="p">:</span>
|
|
<span class="n">props</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">feat</span> <span class="ow">in</span> <span class="n">groupFeatures</span><span class="p">[</span><span class="n">g_id</span><span class="p">]:</span>
|
|
<span class="n">fprops</span> <span class="o">=</span> <span class="n">feat</span><span class="o">.</span><span class="n">props</span>
|
|
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">fprops</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">props</span><span class="p">:</span>
|
|
<span class="n">props</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">fprops</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">props</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">!=</span> <span class="n">fprops</span><span class="p">[</span><span class="n">key</span><span class="p">]:</span>
|
|
<span class="n">props</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="s">"---"</span>
|
|
|
|
<span class="k">if</span> <span class="n">groupAs</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">False</span><span class="p">:</span>
|
|
<span class="n">props</span><span class="p">[</span><span class="n">groupAs</span><span class="p">]</span> <span class="o">=</span> <span class="n">g_id</span>
|
|
<span class="k">if</span> <span class="n">g_id</span> <span class="ow">in</span> <span class="n">groupFeatures</span><span class="p">:</span>
|
|
<span class="n">res</span> <span class="o">+=</span> <span class="n">join_features</span><span class="p">(</span><span class="n">groupFeatures</span><span class="p">[</span><span class="n">g_id</span><span class="p">],</span> <span class="n">props</span><span class="p">)</span>
|
|
<span class="n">layer</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="n">res</span>
|
|
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
<div class='clearall'></div>
|
|
</div>
|
|
</body>
|