AKST / Australian-Address-Boundaries-Land-Property-Price-Database

This is a database of geographic boundaries, addresses as well as land and property data (mostly NSW).
MIT License
1 stars 0 forks source link

Helper for rendering "zoning" #12

Open AKST opened 2 months ago

AKST commented 2 months ago

It would be great to have some helper functions to render the zoning filed in the mesh blocks. It's not as accurate as actually planning data from each state, but it could be to do in the mean time. And I'm sure the matplotlib code can be reused for the actual zoning stuff.

Potential issues

The mb_cat filed in mesh blocks isn't great, but it's kind of fun to do. But the long term solution is figuring out how to map the zoning from the valuer general data on too these shape files, or shape files we end up using for properties.

Long term options

Example

You could do something like this. Fetch data like this

    SELECT mb.mb_cat, mb.geometry as geom
      FROM non_abs_main_structures.lga_2024 lga
      RIGHT JOIN abs_main_structures.meshblock mb ON ST_Intersects(mb.geometry, lga.geometry)
      WHERE lga.lga_name ILIKE 'Sydney'
        AND (ST_Area(ST_Intersection(lga.geometry, mb.geometry)) / ST_Area(mb.geometry)) > 0.1

Then use helpers like this to render the legend and plot.

from collections import defaultdict

mb_cat_facecolor = {
    'Commercial': '#0000ff',
    'Residential': '#ff9999',
    'Education': '#66ff66',
    'Hospital/Medical': '#9933ff',
    'Industrial': '#ffff00',
    'Parkland': 'white',
    'Water': 'white',
    'Transport': 'white',
    'Other': 'white',
}

mb_cat_edgecolor = {
    'Commercial': None,
    'Residential': None,
    'Education': 'white',
    'Hospital/Medical': 'white',
    'Industrial': 'black',
    'Parkland': '#00ff00',
    'Water': '#0000ff',
    'Transport': '#ff0000',
    'Other': 'black',
}

mb_cat_hatch = defaultdict(lambda: None, {
    'Education': '//',
    'Hospital/Medical': '//',
    'Parkland': '//',
    'Water': '//',
    'Transport': '//',
    'Other': '//',
})

def render_zones(ax, df, col):
    cats = list(df[col].unique())
    for c in cats:
        df[df[col] == c].plot(
            ax=ax,
            facecolor=mb_cat_facecolor[c],
            edgecolor=mb_cat_edgecolor[c],
            hatch=mb_cat_hatch[c],
            alpha=mb_cat_alpha[c],
        )

def render_zoning_legend(ax, df, col):
    from matplotlib.patches import Patch
    cats = list(df[col].unique())
    ax.legend(
        handles=[
            Patch(label=c,
                  facecolor=mb_cat_facecolor[c],
                  edgecolor=mb_cat_edgecolor[c],
                  alpha=mb_cat_alpha[c],
                  hatch=mb_cat_hatch[c])
            for c in cats
        ],
        title='Zones',
        loc='lower left',
        fontsize='large',
        title_fontsize='x-large',
    )
image