Skip to content

Commit

Permalink
Merge pull request #69 from VIDA-NYU/request
Browse files Browse the repository at this point in the history
Maintenance
  • Loading branch information
Mary-h86 committed Aug 6, 2024
2 parents 49bbd09 + 99318fd commit 60abaab
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 118 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "tile2net"
version = "0.4.0"
description = "Pedestrian networks from aerial imagery tiles"
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.10,<3.12"
license = { file = "LICENSE" }
keywords = [
"urban-analytics",
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
centerline
jupyter
geopandas
geopandas>=1.0
geopy
matplotlib
momepy
numba
opencv-python
osmnx
Expand Down Expand Up @@ -37,3 +36,4 @@ nbsphinx
pandoc
sphinx-autobuild
sphinx-copybutton
numpy<2.0
3 changes: 2 additions & 1 deletion src/tile2net/raster/geocode.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from __future__ import annotations
from functools import cached_property

import functools
import os.path
from functools import cached_property

from pathlib import Path
from typing import *

Expand Down
14 changes: 11 additions & 3 deletions src/tile2net/raster/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from tile2net.raster.tile_utils.topology import fill_holes, replace_convexhull
from concurrent.futures import ThreadPoolExecutor, Future, as_completed
import shutil

os.environ['USE_PYGEOS'] = '0'
import geopandas as gpd
Expand Down Expand Up @@ -644,8 +645,10 @@ def save_ntw_polygon(self, crs_metric: int = 3857):
simplified.to_crs(self.crs, inplace=True)

self.ntw_poly = simplified
simplified.to_file(
os.path.join(poly_fold, f'{self.name}-Polygons-{datetime.datetime.now().strftime("%d-%m-%Y_%H")}'))
path = os.path.join(poly_fold, f'{self.name}-Polygons-{datetime.datetime.now().strftime("%d-%m-%Y_%H_%M")}')
if os.path.exists(path):
shutil.rmtree(path)
simplified.to_file(path )
logging.info('Polygons are generated and saved!')

def save_ntw_polygons(
Expand Down Expand Up @@ -681,7 +684,12 @@ def save_ntw_polygons(
simplified.to_crs(self.crs, inplace=True)

self.ntw_poly = simplified
path = os.path.join(poly_fold, f'{self.name}-Polygons-{datetime.datetime.now().strftime("%d-%m-%Y_%H")}')
path = os.path.join(
poly_fold,
f'{self.name}-Polygons-{datetime.datetime.now().strftime("%d-%m-%Y_%H_%M")}'
)
if os.path.exists(path):
shutil.rmtree(path)
simplified.to_file(path)
logging.info('Polygons are generated and saved!')

Expand Down
14 changes: 8 additions & 6 deletions src/tile2net/raster/pednet.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import logging
import datetime
import shutil

import pandas as pd
import os

Expand Down Expand Up @@ -300,7 +302,7 @@ def create_sidewalks(self):
#
swntw.geometry = swntw.simplify(0.6)
sw_modif_uni = gpd.GeoDataFrame(
geometry=gpd.GeoSeries([geom for geom in swntw.unary_union.geoms]))
geometry=gpd.GeoSeries([geom for geom in swntw.unary_union.geoms]))
sw_modif_uni_met = set_gdf_crs(sw_modif_uni, 3857)
sw_uni_lines = sw_modif_uni_met.explode()
sw_uni_lines.reset_index(drop=True, inplace=True)
Expand Down Expand Up @@ -412,8 +414,8 @@ def convert_whole_poly2line(self):

for k, v in indcwnear:
island_lines.append(
shapely.shortest_line(self.island.geometry.values[v],
pdfb.geometry.values[k]))
shapely.shortest_line(self.island.geometry.values[v],
pdfb.geometry.values[k]))

island = gpd.GeoDataFrame(geometry=island_lines)

Expand All @@ -435,9 +437,9 @@ def convert_whole_poly2line(self):
path = self.project.network.path

path.mkdir(parents=True, exist_ok=True)
path = path.joinpath(
f'{self.project.name}-Network-{datetime.datetime.now().strftime("%d-%m-%Y_%H")}'
)
path = path.joinpath(f'{self.project.name}-Network-{datetime.datetime.now().strftime("%d-%m-%Y_%H_%M")}')
if os.path.exists(path):
shutil.rmtree(path)
combined.to_file(path)

self.complete_net = combined
48 changes: 31 additions & 17 deletions src/tile2net/raster/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ def __getitem__(
matches: GeoSeries = SourceMeta.coverage.geometry
geocode = GeoCode.from_inferred(item)
loc = matches.intersects(geocode.polygon)
if not loc.any():
if (
not loc.any()
and 'address' in geocode.__dict__
):
# user must've been lazy; compute a new polygon
del geocode.address
_ = geocode.address
Expand All @@ -140,7 +143,10 @@ def __getitem__(
)
loc.append(append)

if not any(loc):
if (
not any(loc)
and 'address' in geocode.__dict__
):
# user must've been lazy; compute a new address
loc = []
del geocode.address
Expand All @@ -159,6 +165,8 @@ def __getitem__(

if any(loc):
matches = matches.loc[loc]
elif 'address' not in geocode.__dict__:
raise SourceNotFound
else:
logger.warning(
f'No keyword matches found for {item=} using '
Expand Down Expand Up @@ -188,18 +196,14 @@ def __getitem__(
raise TypeError(f'Invalid type {type(item)} for {item}')
return source()

def __init__(self: Type[Source], name, bases, attrs, **kwargs):
# super(type(self), self).__init__(name, bases, attrs, **kwargs)
super().__init__(name, bases, attrs)
if (
ABC not in bases
and kwargs.get('init', True)
):
if self.name is None:
raise ValueError(f'{self} must have a name')
if self.name in self.catalog:
raise ValueError(f'{self} name already in use')
self.catalog[self.name] = self
# def __init__(self: Type[Source], name, bases, attrs, **kwargs):
# super().__init__(name, bases, attrs)
# if not getattr(self, 'ignore', False):
# if self.name is None:
# raise ValueError(f'{self} must have a name')
# if self.name in self.catalog:
# raise ValueError(f'{self} name already in use')
# self.catalog[self.name] = self


class Source(ABC, metaclass=SourceMeta):
Expand Down Expand Up @@ -229,8 +233,16 @@ def __str__(self):
return self.name

def __init_subclass__(cls, **kwargs):
# complains if gets kwargs
super().__init_subclass__()
if (
not getattr(cls, 'ignore', False)
and ABC not in cls.__bases__
):
if cls.name is None:
raise ValueError(f'{cls} must have a name')
if cls.name in cls.catalog:
raise ValueError(f'{cls} name already in use')
cls.catalog[cls.name] = cls

def __eq__(self, other):
if (
Expand Down Expand Up @@ -368,6 +380,7 @@ class KingCountyWashington(ArcGis):


class WashingtonDC(ArcGis):
# ignore = True
server = 'https://imagery.dcgis.dc.gov/dcgis/rest/services/Ortho/Ortho_2021/ImageServer'
name = 'dc'
tilesize = 512
Expand Down Expand Up @@ -402,16 +415,17 @@ class LosAngeles(ArcGis):
# raise NotImplementedError


# class WestOregon(ArcGis, init=False):
# class WestOregon(ArcGis):
# ignore = True
# server = 'https://imagery.oregonexplorer.info/arcgis/rest/services/OSIP_2018/OSIP_2018_WM/ImageServer'
# name = 'w_or'
# extension = 'jpeg'
# keyword = 'Oregon'
# # todo: ssl incorrectly configured; come back later
#
# # class EastOregon(ArcGis, init=False):

# class EastOregon(ArcGis, init=False):
# ignore = True
#
# server = 'https://imagery.oregonexplorer.info/arcgis/rest/services/OSIP_2017/OSIP_2017_WM/ImageServer'
# name = 'e_or'
Expand Down
80 changes: 0 additions & 80 deletions src/tile2net/raster/tile_utils/momepy_shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
"Elongation",
"CentroidCorners",
"Linearity",
"CompactnessWeightedAxis",
]


Expand Down Expand Up @@ -1306,82 +1305,3 @@ def _dist(self, a, b):
return math.hypot(b[0] - a[0], b[1] - a[1])


class CompactnessWeightedAxis:
"""
Calculates the compactness-weighted axis of each object in a given GeoDataFrame.
Initially designed for blocks.
.. math::
d_{i} \\times\\left(\\frac{4}{\\pi}-\\frac{16 (area_{i})}
{perimeter_{i}^{2}}\\right)
Parameters
----------
gdf : GeoDataFrame
A GeoDataFrame containing objects.
areas : str, list, np.array, pd.Series (default None)
The name of the dataframe column, ``np.array``, or ``pd.Series`` where
area value are stored . If set to ``None``, this function will calculate areas
during the process without saving them separately.
perimeters : str, list, np.array, pd.Series (default None)
The name of the dataframe column, ``np.array``, or ``pd.Series`` where
perimeter values are stored. If set to ``None``, this function will calculate
perimeters during the process without saving them separately.
longest_axis : str, list, np.array, pd.Series (default None)
The name of the dataframe column, ``np.array``, or ``pd.Series`` where
longest axis length values are stored. If set to ``None``, this function will
calculate longest axis lengths during the process without saving them
separately.
Attributes
----------
series : Series
A Series containing resulting values
gdf : GeoDataFrame
The original GeoDataFrame.
areas : Series
A Series containing used area values.
longest_axis : Series
A Series containing used area values.
perimeters : Series
A Series containing used area values.
Examples
--------
>>> blocks_df['cwa'] = mm.CompactnessWeightedAxis(blocks_df).series
"""

def __init__(self, gdf, areas=None, perimeters=None, longest_axis=None):
self.gdf = gdf
gdf = gdf.copy()

if perimeters is None:
gdf["mm_p"] = gdf.geometry.length
perimeters = "mm_p"
else:
if not isinstance(perimeters, str):
gdf["mm_p"] = perimeters
perimeters = "mm_p"
self.perimeters = gdf[perimeters]
if longest_axis is None:
from momepy.dimension import LongestAxisLength

gdf["mm_la"] = LongestAxisLength(gdf).series
longest_axis = "mm_la"
else:
if not isinstance(longest_axis, str):
gdf["mm_la"] = longest_axis
longest_axis = "mm_la"
self.longest_axis = gdf[longest_axis]
if areas is None:
areas = gdf.geometry.area
if not isinstance(areas, str):
gdf["mm_a"] = areas
areas = "mm_a"
self.areas = gdf[areas]
self.series = pd.Series(
gdf[longest_axis]
* ((4 / np.pi) - (16 * gdf[areas]) / ((gdf[perimeters]) ** 2)),
index=gdf.index,
)

2 changes: 1 addition & 1 deletion src/tile2net/raster/tile_utils/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ def extend_lines(gdf, tolerance, target=None, barrier=None, extension=0):
points = vectorize_points(np.unique(coords[edges], axis=0))

# query LineString geometry to identify points intersecting 2 geometries
inp, res = df.sindex.query_bulk(geo2geodf(points).geometry, predicate="intersects")
inp, res = df.sindex.query(geo2geodf(points).geometry, predicate="intersects")
unique, counts = np.unique(inp, return_counts=True)
ends = np.unique(res[np.isin(inp, unique[counts == 1])])

Expand Down
1 change: 1 addition & 0 deletions src/tile2net/raster/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ def name_from_location(location: str | list[float, str]):
return name
raise TypeError(f"location must be str or list, not {type(location)}")


if __name__ == '__main__':
print(name_from_location('New York, NY, USA'))
print(name_from_location([1.22456789, 2.3456789, 3.456789, 4.56789]))
Expand Down
4 changes: 0 additions & 4 deletions src/tile2net/tileseg/inference/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,6 @@ def inference(args: Namespace):
return inference.inference()


def func( *args, **kwargs ):
...


if __name__ == '__main__':
"""
--city_info /tmp/tile2net/washington_square_park/tiles/washington_square_park_256_info.json --interactive --dump_percent 10
Expand Down
7 changes: 6 additions & 1 deletion src/tile2net/tileseg/utils/trnval_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,12 @@ def validate_topn(val_loader, net, criterion, optim, epoch, args, dump_assets=Tr

output_data = torch.nn.functional.softmax(output, dim=1).cpu().data
op = output_data.cpu().detach().numpy()
np.save(f'{cfg.RESULT_DIR}/output_{epoch}_{val_idx}.npy', op)
path = os.path.join(
cfg.RESULT_DIR,
f'output_{epoch}_{val_idx}.npy'
)
os.makedirs(cfg.RESULT_DIR, exist_ok=True)
np.save(path, op)
prob_mask, predictions = output_data.max(1)
#define assests based on the eval_minibatch function
assets = {}
Expand Down
Loading

0 comments on commit 60abaab

Please sign in to comment.