Implement lod2

This commit is contained in:
Guille Gutierrez 2020-06-22 13:26:50 -04:00
parent 523c96216a
commit 366551cf38
16 changed files with 781249 additions and 89 deletions

View File

@ -10,10 +10,10 @@ class BixiFeature(CityObject):
"""
BixiFeature(CityObject) class
"""
def __init__(self, lod, surfaces, name, feature_type, length):
def __init__(self, lod, surfaces, name, feature_type, coordinates):
super().__init__(lod, surfaces, name)
self._feature_type = feature_type
self._length = length
self._coordinates = coordinates
@property
def feature_type(self):
@ -24,9 +24,9 @@ class BixiFeature(CityObject):
return self._feature_type
@property
def length(self):
def gps_coordinates(self):
"""
Get length of bixi feature in meters
Get bixi feature coordinates
:return: length
"""
return self._length
return self._coordinates

View File

@ -4,12 +4,12 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from __future__ import annotations
from typing import Union
import numpy as np
import pyny3d.geoms as pn
from helpers.geometry_helper import GeometryHelper
@ -418,6 +418,7 @@ class Surface:
intersect_surface = Surface(coordinates, remove_last=False)
if intersect_surface.polygon is None:
return None
return Surface(coordinates, remove_last=False)
except Exception as err:
print('Error', err)

Binary file not shown.

Binary file not shown.

View File

@ -492,7 +492,7 @@
</li>
<li><a href="index.html#city_model_structure.layer.Layer.material">material() (city_model_structure.layer.Layer property)</a>
</li>
<li><a href="index.html#city_model_structure.building.Building.max_height">max_height() (city_model_structure.building.Building property)</a>
<li><a href="index.html#city_model_structure.city_object.CityObject.max_height">max_height() (city_model_structure.city_object.CityObject property)</a>
</li>
<li><a href="index.html#city_model_structure.polyhedron.Polyhedron.max_z">max_z() (city_model_structure.polyhedron.Polyhedron property)</a>
</li>
@ -640,7 +640,7 @@
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#city_model_structure.building.Building.stl_export">stl_export() (city_model_structure.building.Building method)</a>
<li><a href="index.html#city_model_structure.city_object.CityObject.stl_export">stl_export() (city_model_structure.city_object.CityObject method)</a>
</li>
<li><a href="index.html#city_model_structure.building.Building.storeys_above_ground">storeys_above_ground() (city_model_structure.building.Building property)</a>
</li>

View File

@ -215,7 +215,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez <a class="reference external" href="mailto:guillermo&#46;gutierrezmorote&#37;&#52;&#48;concordia&#46;ca">guillermo<span>&#46;</span>gutierrezmorote<span>&#64;</span>concordia<span>&#46;</span>ca</a></p>
<dl class="py class">
<dt id="city_model_structure.city_object.CityObject">
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.city_object.</code><code class="sig-name descname">CityObject</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/city_object.html#CityObject"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.city_object.CityObject" title="Permalink to this definition"></a></dt>
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.city_object.</code><code class="sig-name descname">CityObject</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em>, <em class="sig-param"><span class="n">name</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/city_object.html#CityObject"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.city_object.CityObject" title="Permalink to this definition"></a></dt>
<dd><p>class CityObject</p>
<dl class="py method">
<dt id="city_model_structure.city_object.CityObject.location">
@ -231,6 +231,21 @@ Copyright © 2020 Project Author Guille Gutierrez <a class="reference external"
:return: int</p>
</dd></dl>
<dl class="py method">
<dt id="city_model_structure.city_object.CityObject.max_height">
<em class="property">property </em><code class="sig-name descname">max_height</code><a class="headerlink" href="#city_model_structure.city_object.CityObject.max_height" title="Permalink to this definition"></a></dt>
<dd><p>City object maximal height in meters
:return: float</p>
</dd></dl>
<dl class="py method">
<dt id="city_model_structure.city_object.CityObject.stl_export">
<code class="sig-name descname">stl_export</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">path</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/city_object.html#CityObject.stl_export"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.city_object.CityObject.stl_export" title="Permalink to this definition"></a></dt>
<dd><p>Export the city object to stl file (city_object_name.stl) to the given path
:param path: str
:return: None</p>
</dd></dl>
<dl class="py method">
<dt id="city_model_structure.city_object.CityObject.surface">
<code class="sig-name descname">surface</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em><span class="sig-paren">)</span> &#x2192; Optional<span class="p">[</span><a class="reference internal" href="#city_model_structure.surface.Surface" title="city_model_structure.surface.Surface">city_model_structure.surface.Surface</a><span class="p">]</span><a class="reference internal" href="_modules/city_model_structure/city_object.html#CityObject.surface"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.city_object.CityObject.surface" title="Permalink to this definition"></a></dt>
@ -263,7 +278,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez <a class="reference external" href="mailto:guillermo&#46;gutierrezmorote&#37;&#52;&#48;concordia&#46;ca">guillermo<span>&#46;</span>gutierrezmorote<span>&#64;</span>concordia<span>&#46;</span>ca</a></p>
<dl class="py class">
<dt id="city_model_structure.bixi_feature.BixiFeature">
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.bixi_feature.</code><code class="sig-name descname">BixiFeature</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em>, <em class="sig-param"><span class="n">feature_type</span></em>, <em class="sig-param"><span class="n">length</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/bixi_feature.html#BixiFeature"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.bixi_feature.BixiFeature" title="Permalink to this definition"></a></dt>
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.bixi_feature.</code><code class="sig-name descname">BixiFeature</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em>, <em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">feature_type</span></em>, <em class="sig-param"><span class="n">length</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/bixi_feature.html#BixiFeature"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.bixi_feature.BixiFeature" title="Permalink to this definition"></a></dt>
<dd><p>BixiFeature(CityObject) class</p>
<dl class="py method">
<dt id="city_model_structure.bixi_feature.BixiFeature.feature_type">
@ -333,13 +348,6 @@ Copyright © 2020 Project Author Guille Gutierrez <a class="reference external"
:return: float</p>
</dd></dl>
<dl class="py method">
<dt id="city_model_structure.building.Building.max_height">
<em class="property">property </em><code class="sig-name descname">max_height</code><a class="headerlink" href="#city_model_structure.building.Building.max_height" title="Permalink to this definition"></a></dt>
<dd><p>City object maximal height in meters
:return: float</p>
</dd></dl>
<dl class="py method">
<dt id="city_model_structure.building.Building.name">
<em class="property">property </em><code class="sig-name descname">name</code><a class="headerlink" href="#city_model_structure.building.Building.name" title="Permalink to this definition"></a></dt>
@ -347,14 +355,6 @@ Copyright © 2020 Project Author Guille Gutierrez <a class="reference external"
:return: str</p>
</dd></dl>
<dl class="py method">
<dt id="city_model_structure.building.Building.stl_export">
<code class="sig-name descname">stl_export</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">path</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/building.html#Building.stl_export"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.building.Building.stl_export" title="Permalink to this definition"></a></dt>
<dd><p>Export the city object to stl file (city_object_name.stl) to the given path
:param path: str
:return: None</p>
</dd></dl>
<dl class="py method">
<dt id="city_model_structure.building.Building.storeys_above_ground">
<em class="property">property </em><code class="sig-name descname">storeys_above_ground</code><a class="headerlink" href="#city_model_structure.building.Building.storeys_above_ground" title="Permalink to this definition"></a></dt>
@ -407,7 +407,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez <a class="reference external" href="mailto:guillermo&#46;gutierrezmorote&#37;&#52;&#48;concordia&#46;ca">guillermo<span>&#46;</span>gutierrezmorote<span>&#64;</span>concordia<span>&#46;</span>ca</a></p>
<dl class="py class">
<dt id="city_model_structure.composting_plant.CompostingPlant">
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.composting_plant.</code><code class="sig-name descname">CompostingPlant</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em>, <em class="sig-param"><span class="n">waste_type</span></em>, <em class="sig-param"><span class="n">capacity</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/composting_plant.html#CompostingPlant"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.composting_plant.CompostingPlant" title="Permalink to this definition"></a></dt>
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.composting_plant.</code><code class="sig-name descname">CompostingPlant</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em>, <em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">waste_type</span></em>, <em class="sig-param"><span class="n">capacity</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/composting_plant.html#CompostingPlant"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.composting_plant.CompostingPlant" title="Permalink to this definition"></a></dt>
<dd><p>CompostingPlant(CityObject) class</p>
<dl class="py method">
<dt id="city_model_structure.composting_plant.CompostingPlant.capacity">
@ -433,7 +433,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez <a class="reference external" href="mailto:guillermo&#46;gutierrezmorote&#37;&#52;&#48;concordia&#46;ca">guillermo<span>&#46;</span>gutierrezmorote<span>&#64;</span>concordia<span>&#46;</span>ca</a></p>
<dl class="py class">
<dt id="city_model_structure.tree.Tree">
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.tree.</code><code class="sig-name descname">Tree</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em>, <em class="sig-param"><span class="n">height</span></em>, <em class="sig-param"><span class="n">canopy</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/tree.html#Tree"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.tree.Tree" title="Permalink to this definition"></a></dt>
<em class="property">class </em><code class="sig-prename descclassname">city_model_structure.tree.</code><code class="sig-name descname">Tree</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">lod</span></em>, <em class="sig-param"><span class="n">surfaces</span></em>, <em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">height</span></em>, <em class="sig-param"><span class="n">canopy</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/city_model_structure/tree.html#Tree"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#city_model_structure.tree.Tree" title="Permalink to this definition"></a></dt>
<dd><p>Tree(CityObject) class</p>
<dl class="py method">
<dt id="city_model_structure.tree.Tree.canopy">

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,7 @@ from city_model_structure.city import City
from city_model_structure.building import Building
from city_model_structure.surface import Surface
from helpers.geometry_helper import GeometryHelper
from datetime import datetime
class CityGml:
@ -17,11 +18,20 @@ class CityGml:
CityGml class
"""
def __init__(self, path):
start = datetime.utcnow()
self._city = None
with open(path) as gml:
# Clean the namespaces is an important task to prevent wrong ns:field due poor citygml implementations
self._gml = xmltodict.parse(gml.read(), process_namespaces=True, xml_attribs=True, namespaces={
'http://www.opengis.net/gml': None,
'http://www.opengis.net/citygml/1.0': None,
'http://www.opengis.net/citygml/building/1.0': None,
'http://schemas.opengis.net/citygml/building/1.0/building.xsd': None,
'http://www.opengis.net/citygml/appearance/1.0': None,
'http://schemas.opengis.net/citygml/appearance/1.0/appearance.xsd': None,
'http://www.opengis.net/citygml/relief/1.0': None,
'http://schemas.opengis.net/citygml/relief/1.0/relief.xsd': None,
'http://www.opengis.net/citygml/generics/1.0': None,
'http://www.w3.org/2001/XMLSchema-instance': None,
'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0': None,
'http://www.w3.org/1999/xlink': None,
@ -31,18 +41,20 @@ class CityGml:
'http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd" '
'xmlns="http://www.opengis.net/citygml/2.0': None,
'http://www.opengis.net/citygml/2.0': None
}, force_list=('cityObjectMember', 'curveMember'))
}, force_list=('cityObjectMember', 'curveMember', 'boundedBy', 'surfaceMember'))
self._city_objects = None
self._geometry = GeometryHelper()
envelope = self._gml['CityModel']['boundedBy']['Envelope']
if '#text' in envelope['lowerCorner']:
self._lower_corner = np.fromstring(envelope['lowerCorner']['#text'], dtype=float, sep=' ')
self._upper_corner = np.fromstring(envelope['upperCorner']['#text'], dtype=float, sep=' ')
else:
self._lower_corner = np.fromstring(envelope['lowerCorner'], dtype=float, sep=' ')
self._upper_corner = np.fromstring(envelope['upperCorner'], dtype=float, sep=' ')
for bound in self._gml['CityModel']['boundedBy']:
envelope = bound['Envelope']
if '#text' in envelope['lowerCorner']:
self._lower_corner = np.fromstring(envelope['lowerCorner']['#text'], dtype=float, sep=' ')
self._upper_corner = np.fromstring(envelope['upperCorner']['#text'], dtype=float, sep=' ')
else:
self._lower_corner = np.fromstring(envelope['lowerCorner'], dtype=float, sep=' ')
self._upper_corner = np.fromstring(envelope['upperCorner'], dtype=float, sep=' ')
self._srs_name = envelope['@srsName']
self._srs_name = envelope['@srsName']
print('city_gml constructor', datetime.utcnow() - start)
@property
def content(self):
@ -60,55 +72,35 @@ class CityGml:
"""
if self._city is None:
self._city = City(self._lower_corner, self._upper_corner, self._srs_name)
i = 0
for o in self._gml['CityModel']['cityObjectMember']:
i += 1
print('add city object', i)
lod = 0
surfaces = []
if 'lod1Solid' in o['Building']:
lod += 1
if 'lod2Solid' in o['Building']:
lod += 2
if 'lod3Solid' in o['Building']:
lod += 4
if 'lod4Solid' in o['Building']:
lod += 8
# ToDo: this is specific for Lod1 need to be modeled for higher lod's and lod combinations
surfaces = self._lod1(o)
for bound in o['Building']['boundedBy']:
surface_type = next(iter(bound))
if 'lod2MultiSurface' in bound[surface_type]:
start = datetime.utcnow()
lod = 2
surfaces = CityGml._lod2(bound)
print('lod2 ', surface_type, datetime.utcnow() - start)
if 'lod3Solid' in o['Building']:
lod += 4
if 'lod4Solid' in o['Building']:
lod += 8
name = o['Building']['@id']
lod_str = 'lod' + str(lod) + 'Solid'
lod_terrain_str = 'lod' + str(lod) + 'TerrainIntersection'
try:
surfaces = [Surface(s['Polygon']['exterior']['LinearRing']['posList']['#text'])
for s in o['Building'][lod_str]['Solid']['exterior']['CompositeSurface']['surfaceMember']]
except TypeError:
surfaces = [Surface(s['Polygon']['exterior']['LinearRing']['posList'])
for s in o['Building'][lod_str]['Solid']['exterior']['CompositeSurface']['surfaceMember']]
terrains = []
if lod_terrain_str in o['Building']:
try:
curves = [c['LineString']['posList']['#text']
for c in o['Building'][lod_terrain_str]['MultiCurve']['curveMember']]
except TypeError:
curves = [c['LineString']['posList']
for c in o['Building'][lod_terrain_str]['MultiCurve']['curveMember']]
terrains = self._terrains(o, lod_terrain_str)
terrains = []
for curve in curves:
curve_points = np.fromstring(curve, dtype=float, sep=' ')
curve_points = self._geometry.to_points_matrix(curve_points, True)
terrains.append(curve_points)
else:
terrains = []
for s in surfaces:
ground = True
ground_points = []
for row in s.points:
# all surface vertex are in the lower z
ground_point = [row[0], row[1], self._lower_corner[2]]
ground_points = np.concatenate((ground_points, ground_point), axis=None)
ground = ground and self._geometry.almost_equal(row, ground_point)
if ground:
ground_points = self._geometry.to_points_matrix(ground_points)
# Do i need to remove the duplicated?
terrains.append(ground_points)
year_of_construction = None
function = None
if 'yearOfConstruction' in o['Building']:
@ -118,3 +110,56 @@ class CityGml:
self._city.add_city_object(Building(name, lod, surfaces, terrains, year_of_construction, function,
self._lower_corner))
return self._city
def _terrains(self, city_object, lod_terrain_str):
try:
curves = [c['LineString']['posList']['#text']
for c in city_object['Building'][lod_terrain_str]['MultiCurve']['curveMember']]
except TypeError:
curves = [c['LineString']['posList']
for c in city_object['Building'][lod_terrain_str]['MultiCurve']['curveMember']]
terrains = []
for curve in curves:
curve_points = np.fromstring(curve, dtype=float, sep=' ')
curve_points = self._geometry.to_points_matrix(curve_points, True)
terrains.append(curve_points)
return terrains
def _lod1(self, o):
try:
surfaces = [Surface(s['Polygon']['exterior']['LinearRing']['posList']['#text'])
for s in o['Building']['lod1Solid']['Solid']['exterior']['CompositeSurface']['surfaceMember']]
except TypeError:
surfaces = [Surface(s['Polygon']['exterior']['LinearRing']['posList'])
for s in o['Building']['lod1Solid']['Solid']['exterior']['CompositeSurface']['surfaceMember']]
terrains = []
for s in surfaces:
ground = True
ground_points = []
for row in s.points:
# all surface vertex are in the lower z
ground_point = [row[0], row[1], self._lower_corner[2]]
ground_points = np.concatenate((ground_points, ground_point), axis=None)
ground = ground and self._geometry.almost_equal(row, ground_point)
if ground:
ground_points = self._geometry.to_points_matrix(ground_points)
# Do i need to remove the duplicated?
terrains.append(ground_points)
return surfaces
@staticmethod
def _lod2(bound):
surfaces = []
for surface_type in iter(bound):
for s in bound[surface_type]['lod2MultiSurface']['MultiSurface']['surfaceMember']:
try:
surfaces = [Surface(s['Polygon']['exterior']['LinearRing']['posList']['#text'],
surface_type=GeometryHelper.gml_surface_to_libs(surface_type))
for s in bound[surface_type]['lod2MultiSurface']['MultiSurface']['surfaceMember']]
except TypeError:
surfaces = [Surface(s['Polygon']['exterior']['LinearRing']['posList'],
surface_type=GeometryHelper.gml_surface_to_libs(surface_type))
for s in bound[surface_type]['lod2MultiSurface']['MultiSurface']['surfaceMember']]
print(len(surfaces), 'surfaces')
return surfaces

View File

@ -4,6 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
import math
from datetime import datetime
import numpy as np
import open3d as o3d
@ -35,6 +36,8 @@ class GeometryHelper:
:param s2: Surface
:return: Boolean
"""
start = datetime.utcnow()
# delta is grads an need to be converted into radians
delta = np.rad2deg(self._delta)
difference = (s1.inclination - s2.inclination) % math.pi
@ -58,6 +61,7 @@ class GeometryHelper:
minimum_distance = distance
if minimum_distance <= self._delta:
break
print('intersect', datetime.utcnow() - start)
if minimum_distance > self._delta or s1.intersect(s2) is None:
return False
else:
@ -163,3 +167,12 @@ class GeometryHelper:
mesh_final.append(GeometryHelper._merge_meshes(mesh_1, mesh_2))
return mesh_final
@staticmethod
def gml_surface_to_libs(surface):
if surface == 'WallSurface':
return 'Wall'
elif surface == 'GroundSurface':
return 'Ground'
else:
return 'Roof'

View File

@ -24,7 +24,7 @@ class TestGeometryFactory(TestCase):
def _get_citygml(self):
if self._city_gml is None:
file_path = (self._example_path / 'buildings.gml').resolve()
file_path = (self._example_path / 'lod2_buildings.gml').resolve()
self._city_gml = GeometryFactory('citygml', file_path).city
self.assertIsNotNone(self._city_gml, 'city is none')
return self._city_gml
@ -35,8 +35,8 @@ class TestGeometryFactory(TestCase):
:return: None
"""
city = self._get_citygml()
self.assertIsNotNone(city.buildings, 'city_objects is none')
for city_object in city.buildings:
self.assertIsNotNone(city.city_objects, 'city_objects is none')
for city_object in city.city_objects:
self.assertIsNotNone(city.city_object(city_object.name), 'city_object return none')
self.assertIsNotNone(city.srs_name, 'srs_name is none')
self.assertIsNotNone(city.lower_corner, 'lower_corner is none')

View File

@ -25,7 +25,7 @@ class TestPhysicsFactory(TestCase):
def _get_citygml(self):
if self._city_gml is None:
file_path = (self._example_path / 'buildings.gml').resolve()
file_path = (self._example_path / 'lod2_buildings.gml').resolve()
self._city_gml = GeometryFactory('citygml', file_path).city
self.assertIsNotNone(self._city_gml, 'city is none')
return self._city_gml

781101
tests_data/lod2_buildings.gml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1713,7 +1713,7 @@ class LightSource:
completely in shadow and 1 is completely illuminated.
"""
# Because most image and raster GIS data has the first row in the array
# Because most image and raster gis data has the first row in the array
# as the "top" of the image, dy is implicitly negative. This is
# consistent to what `imshow` assumes, as well.
dy = -dy

View File

@ -62,7 +62,7 @@ class TransformerGroup(_TransformerGroup):
projections are equivalent. Default is false.
always_xy: bool, optional
If true, the transform method will accept as input and return as output
coordinates using the traditional GIS order, that is longitude, latitude
coordinates using the traditional gis order, that is longitude, latitude
for geographic CRS and easting, northing for most projected CRS.
Default is false.
area_of_interest: :class:`pyproj.transformer.AreaOfInterest`, optional
@ -246,7 +246,7 @@ class Transformer:
projections are equivalent. Default is false.
always_xy: bool, optional
If true, the transform method will accept as input and return as output
coordinates using the traditional GIS order, that is longitude, latitude
coordinates using the traditional gis order, that is longitude, latitude
for geographic CRS and easting, northing for most projected CRS.
Default is false.
area_of_interest: :class:`pyproj.transformer.AreaOfInterest`, optional
@ -295,7 +295,7 @@ class Transformer:
projections are equivalent. Default is false.
always_xy: bool, optional
If true, the transform method will accept as input and return as output
coordinates using the traditional GIS order, that is longitude, latitude
coordinates using the traditional gis order, that is longitude, latitude
for geographic CRS and easting, northing for most projected CRS.
Default is false.
area_of_interest: :class:`pyproj.transformer.AreaOfInterest`, optional
@ -699,7 +699,7 @@ def transform(
it will skip the transformation operation if input and output
projections are equivalent. If `always_xy` is toggled, the
transform method will accept as input and return as output
coordinates using the traditional GIS order, that is longitude, latitude
coordinates using the traditional gis order, that is longitude, latitude
for geographic CRS and easting, northing for most projected CRS.
In addition to converting between cartographic and geographic
@ -807,7 +807,7 @@ def itransform(
it will skip the transformation operation if input and output
projections are equivalent. If `always_xy` is toggled, the
transform method will accept as input and return as output
coordinates using the traditional GIS order, that is longitude, latitude
coordinates using the traditional gis order, that is longitude, latitude
for geographic CRS and easting, northing for most projected CRS.

View File

@ -5391,7 +5391,7 @@ class kappa3_gen(rv_continuous):
References
----------
P.W. Mielke and E.S. Johnson, "Three-Parameter Kappa Distribution Maximum
Likelihood and Likelihood Ratio Tests", Methods in Weather Research,
Likelihood and Likelihood Ratio Tests", Methods in weather Research,
701-707, (September, 1973),
https://doi.org/10.1175/1520-0493(1973)101<0701:TKDMLE>2.3.CO;2