зеркало из https://github.com/microsoft/landcover.git
Refactoring of datasets
This commit is contained in:
Родитель
5dd74266b8
Коммит
4574431fab
|
@ -1,697 +1,23 @@
|
|||
import os
|
||||
import json
|
||||
|
||||
import utm
|
||||
import fiona
|
||||
import fiona.transform
|
||||
import shapely
|
||||
import shapely.geometry
|
||||
from enum import Enum
|
||||
|
||||
from web_tool import ROOT_DIR
|
||||
|
||||
from DataLoader import DataLoaderCustom, DataLoaderUSALayer, DataLoaderBasemap
|
||||
|
||||
class DatasetTypes(Enum):
|
||||
CUSTOM = 1
|
||||
USA_LAYER = 2
|
||||
BASEMAP = 3
|
||||
_DATASET_FN = "data/datasets.json"
|
||||
|
||||
DATASETS = {} # This dictionary should be the only thing imported from other files
|
||||
DATASET_DEFINITIONS = {
|
||||
"esri_world_imagery": {
|
||||
"name": "ESRI World Imagery",
|
||||
"imagery_metadata": "ESRI World Imagery",
|
||||
"data_layer_type": DatasetTypes.BASEMAP,
|
||||
"data_url": 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
|
||||
"data_padding": 0.0005,
|
||||
"leafletTileLayer": {
|
||||
"url": 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
|
||||
"args": {
|
||||
"minZoom": 4,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
}
|
||||
},
|
||||
"shape_layers": None,
|
||||
"location": {
|
||||
"center": [38, -88],
|
||||
"initialZoom": 4,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"esri_world_imagery_naip": {
|
||||
"name": "ESRI World Imagery",
|
||||
"imagery_metadata": "ESRI World Imagery",
|
||||
"data_layer_type": DatasetTypes.USA_LAYER,
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"url": 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
|
||||
"args": {
|
||||
"minZoom": 4,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
}
|
||||
},
|
||||
"shape_layers": None,
|
||||
"location": {
|
||||
"center": [38, -88],
|
||||
"initialZoom": 4,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"user_study_5": {
|
||||
"name": "User Study Area 5",
|
||||
"imagery_metadata": "NAIP Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/user_study_5.tif",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/user_study_5/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 13,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Area boundary", "shapes_fn": "shapes/user_study_5_outline.geojson", "zone_name_key": None}
|
||||
],
|
||||
"location": {
|
||||
"center": [42.448269618302362, -75.110429001207137],
|
||||
"initialZoom": 13,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"leuser": {
|
||||
"name": "Sumatra",
|
||||
"imagery_metadata": "Planet",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/merged_4m_rgb.tif",
|
||||
"data_padding": 500,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/leuser/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 16,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Btoru", "shapes_fn": "shapes/btoru_aoi_extent.geojson", "zone_name_key": "MINX"},
|
||||
{"name": "Atimur", "shapes_fn": "shapes/atimur_aoi_extent.geojson", "zone_name_key": "MINX"},
|
||||
],
|
||||
"location": {
|
||||
"center": [4.1828740090001588, 97.418702680771901],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"yangon_sentinel": {
|
||||
"name": "Yangon, Myanmar",
|
||||
"imagery_metadata": "Sentinel Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/yangon.tif",
|
||||
"data_padding": 1100,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/yangon/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 10,
|
||||
"maxNativeZoom": 16,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "States", "shapes_fn": "shapes/yangon_sentinel_admin_1_clipped.geojson", "zone_name_key": "ST"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/yangon_sentinel_admin_2_clipped.geojson", "zone_name_key": "DT"},
|
||||
{"name": "Townships", "shapes_fn": "shapes/yangon_sentinel_admin_3_clipped.geojson", "zone_name_key": "TS"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/yangon_sentinel_admin_4_clipped.geojson", "zone_name_key": "Ward"}
|
||||
],
|
||||
"location": {
|
||||
"center": [16.66177, 96.326427],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"hcmc_sentinel": {
|
||||
"name": "Hồ Chí Minh City, Vietnam",
|
||||
"imagery_metadata": "Sentinel Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/hcmc_sentinel.tif",
|
||||
"data_padding": 1100,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/hcmc_sentinel_tiles/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 10,
|
||||
"maxNativeZoom": 16,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Provinces", "shapes_fn": "shapes/hcmc_sentinel_admin_1_clipped.geojson", "zone_name_key": "NAME_1"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/hcmc_sentinel_admin_2_clipped.geojson", "zone_name_key": "NAME_2"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/hcmc_sentinel_admin_3_clipped.geojson", "zone_name_key": "NAME_3"}
|
||||
],
|
||||
"location": {
|
||||
"center": [10.682, 106.752],
|
||||
"initialZoom": 11,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"hcmc_sentinel_2017": {
|
||||
"name": "Hồ Chí Minh City, Vietnam",
|
||||
"imagery_metadata": "Sentinel Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/hcmc_sentinel_2017_01_08.tif",
|
||||
"data_padding": 1100,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/hcmc_sentinel_2017_01_08/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 10,
|
||||
"maxNativeZoom": 16,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Provinces", "shapes_fn": "shapes/hcmc_sentinel_admin_1_clipped.geojson", "zone_name_key": "NAME_1"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/hcmc_sentinel_admin_2_clipped.geojson", "zone_name_key": "NAME_2"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/hcmc_sentinel_admin_3_clipped.geojson", "zone_name_key": "NAME_3"}
|
||||
],
|
||||
"location": {
|
||||
"center": [10.682, 106.752],
|
||||
"initialZoom": 11,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"hcmc_spot_2019": {
|
||||
"name": "Hồ Chí Minh City, Vietnam",
|
||||
"imagery_metadata": "SPOT Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
#"data_fn": "tiles/spot6_2019_02_10.tif",
|
||||
"data_fn": "tiles/nhabe_spot_stacked_2019.tif",
|
||||
"data_padding": 10,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/spot6_2019_02_10/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 13,
|
||||
"maxNativeZoom": 16,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Provinces", "shapes_fn": "shapes/hcmc_sentinel_admin_1_clipped.geojson", "zone_name_key": "NAME_1"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/hcmc_sentinel_admin_2_clipped.geojson", "zone_name_key": "NAME_2"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/hcmc_sentinel_admin_3_clipped.geojson", "zone_name_key": "NAME_3"}
|
||||
],
|
||||
"location": {
|
||||
"center": [10.682, 106.752],
|
||||
"initialZoom": 13,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"hcmc_spot_2017": {
|
||||
"name": "Hồ Chí Minh City, Vietnam",
|
||||
"imagery_metadata": "SPOT Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
#"data_fn": "tiles/spot6_2017_02_12.tif",
|
||||
"data_fn": "tiles/nhabe_spot_stacked_2017.tif",
|
||||
"data_padding": 10,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/spot6_2017_02_12/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 13,
|
||||
"maxNativeZoom": 16,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Provinces", "shapes_fn": "shapes/hcmc_sentinel_admin_1_clipped.geojson", "zone_name_key": "NAME_1"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/hcmc_sentinel_admin_2_clipped.geojson", "zone_name_key": "NAME_2"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/hcmc_sentinel_admin_3_clipped.geojson", "zone_name_key": "NAME_3"}
|
||||
],
|
||||
"location": {
|
||||
"center": [10.682, 106.752],
|
||||
"initialZoom": 13,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"hcmc_pleadies_2019": {
|
||||
"name": "Hồ Chí Minh City, Vietnam",
|
||||
"imagery_metadata": "Pleadies Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/pleadies_2019_02_10.tif",
|
||||
"data_padding": 0,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/pleadies_2019_02_10/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 13,
|
||||
"maxNativeZoom": 16,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Provinces", "shapes_fn": "shapes/hcmc_sentinel_admin_1_clipped.geojson", "zone_name_key": "NAME_1"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/hcmc_sentinel_admin_2_clipped.geojson", "zone_name_key": "NAME_2"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/hcmc_sentinel_admin_3_clipped.geojson", "zone_name_key": "NAME_3"}
|
||||
],
|
||||
"location": {
|
||||
"center": [10.682, 106.752],
|
||||
"initialZoom": 13,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"yangon_lidar": {
|
||||
"name": "Yangon, Myanmar",
|
||||
"imagery_metadata": "LiDAR Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/yangon_lidar.tif",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/yangon_lidar/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 10,
|
||||
"maxNativeZoom": 20,
|
||||
"maxZoom": 21,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "States", "shapes_fn": "shapes/yangon_lidar_admin_1_clipped.geojson", "zone_name_key": "ST"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/yangon_lidar_admin_2_clipped.geojson", "zone_name_key": "DT"},
|
||||
{"name": "Townships", "shapes_fn": "shapes/yangon_lidar_admin_3_clipped.geojson", "zone_name_key": "TS"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/yangon_lidar_admin_4_clipped.geojson", "zone_name_key": "Ward"}
|
||||
],
|
||||
"location": {
|
||||
"center": [16.7870, 96.1450],
|
||||
"initialZoom": 15,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"hcmc_dg": {
|
||||
"name": "Thủ Đức District, Hồ Chí Minh City, Vietnam",
|
||||
"imagery_metadata": "Digital Globe Imagery",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/HCMC.tif",
|
||||
"data_padding": 0,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/HCMC/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 14,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 21,
|
||||
"attribution": 'Georeferenced Image'
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Provinces", "shapes_fn": "shapes/hcmc_digital-globe_admin_1_clipped.geojson", "zone_name_key": "NAME_1"},
|
||||
{"name": "Districts", "shapes_fn": "shapes/hcmc_digital-globe_admin_2_clipped.geojson", "zone_name_key": "NAME_2"},
|
||||
{"name": "Wards", "shapes_fn": "shapes/hcmc_digital-globe_admin_3_clipped.geojson", "zone_name_key": "NAME_3"}
|
||||
],
|
||||
"location": {
|
||||
"center": [10.838, 106.750],
|
||||
"initialZoom": 14,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"airbus": {
|
||||
"name": "Virginia, USA",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"imagery_metadata": "Airbus Imagery",
|
||||
"data_fn": "tiles/airbus_epsg4326.tif",
|
||||
"data_padding": 0.003,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/airbus/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 13,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 21,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "Grid", "shapes_fn": "shapes/airbus-data-grid-epsg4326.geojson", "zone_name_key": "id"}
|
||||
],
|
||||
"location": {
|
||||
"center": [36.80, -76.12],
|
||||
"initialZoom": 14,
|
||||
"bounds": [[36.882932, -76.2623637], [36.7298842, -76.0249016]]
|
||||
}
|
||||
},
|
||||
"chesapeake": {
|
||||
"name": "Maryland, USA",
|
||||
"data_layer_type": DatasetTypes.USA_LAYER,
|
||||
"imagery_metadata": "NAIP Imagery",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"url": 'tiles/chesapeake_test/{z}/{x}/{y}.png',
|
||||
"args": {
|
||||
"tms": True,
|
||||
"minZoom": 2,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": None,
|
||||
"location": {
|
||||
"center": [38.11437, -75.99980],
|
||||
"initialZoom": 10,
|
||||
}
|
||||
},
|
||||
"florida_keys_2010_wmts": {
|
||||
"name": "Florida Keys, 2010",
|
||||
"imagery_metadata": "NAIP 2010",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/florida_keys_2010.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:florida_keys_2010_rgb&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/florida_keys_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [24.7007, -81.3847],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"florida_keys_2013_wmts": {
|
||||
"name": "Florida Keys, 2013",
|
||||
"imagery_metadata": "NAIP 2013",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/florida_keys_2013.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:florida_keys_2013_rgb&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/florida_keys_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [24.7007, -81.3847],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"florida_keys_2015_wmts": {
|
||||
"name": "Florida Keys, 2015",
|
||||
"imagery_metadata": "NAIP 2015",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/florida_keys_2015.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:florida_keys_2015_rgb&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/florida_keys_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [24.7007, -81.3847],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_2010_wmts": {
|
||||
"name": "LA Coast, 2010",
|
||||
"imagery_metadata": "NAIP 2010",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2010.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_2010_rgb&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_2013_wmts": {
|
||||
"name": "LA Coast, 2013",
|
||||
"imagery_metadata": "NAIP 2013",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2013.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_2013_rgb&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_2015_wmts": {
|
||||
"name": "LA Coast, 2015",
|
||||
"imagery_metadata": "NAIP 2015",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2015.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_2015_rgb&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_nlcd_wmts": {
|
||||
"name": "LA Coast, NLCD Ground Truth Old",
|
||||
"imagery_metadata": "Ground Truth",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2013.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_nlcd&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_nlcd_2011_wmts": {
|
||||
"name": "LA Coast, NLCD Ground Truth 2011",
|
||||
"imagery_metadata": "Ground Truth",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2013.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_nlcd_2011&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_nlcd_2013_wmts": {
|
||||
"name": "LA Coast, NLCD Ground Truth 2013",
|
||||
"imagery_metadata": "Ground Truth",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2013.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_nlcd_2013&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_nlcd_2016_wmts": {
|
||||
"name": "LA Coast, NLCD Ground Truth 2016",
|
||||
"imagery_metadata": "Ground Truth",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2013.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_nlcd_2016&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_embed_2010_wmts": {
|
||||
"name": "LA Coast, 2010",
|
||||
"imagery_metadata": "Embedded NLCD 2010",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2010.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_embed_2010&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
},
|
||||
"la_coast_embed_2013_wmts": {
|
||||
"name": "LA Coast, 2013",
|
||||
"imagery_metadata": "Embedded NLCD 2013",
|
||||
"data_layer_type": DatasetTypes.CUSTOM,
|
||||
"data_fn": "tiles/la_coast_2013.vrt",
|
||||
"data_padding": 20,
|
||||
"leafletTileLayer": {
|
||||
"wms": False,
|
||||
"url": 'http://msrcalebgeoserver.eastus.cloudapp.azure.com:8080/geoserver/gwc/service/wmts?layer=local:la_coast_embed_2013&style=&tilematrixset=EPSG:3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix=EPSG:3857:{z}&TileCol={x}&TileRow={y}',
|
||||
"args": {
|
||||
"tms": False,
|
||||
"minZoom": 8,
|
||||
"maxNativeZoom": 18,
|
||||
"maxZoom": 20,
|
||||
"attribution": 'Georeferenced Image',
|
||||
}
|
||||
},
|
||||
"shape_layers": [
|
||||
{"name": "NAIP tiles", "shapes_fn": "shapes/la_coast_29090_2010_tiles.geojson", "zone_name_key": "location"}
|
||||
],
|
||||
"location": {
|
||||
"center": [29.598, -90.559],
|
||||
"initialZoom": 10,
|
||||
"bounds": None
|
||||
}
|
||||
}
|
||||
}
|
||||
def _load_geojson_as_list(fn):
|
||||
''' Takes a geojson file as input and outputs a list of shapely `shape` objects in that file and their corresponding areas in km^2.
|
||||
|
||||
|
||||
def load_geojson_as_list(fn):
|
||||
We calculate area here by re-projecting the shape into its local UTM zone, converting it to a shapely `shape`, then using the `.area` property.
|
||||
'''
|
||||
shapes = []
|
||||
areas = []
|
||||
crs = None
|
||||
|
@ -718,80 +44,52 @@ def load_geojson_as_list(fn):
|
|||
return shapes, areas, src_crs
|
||||
|
||||
|
||||
def get_javascript_string_from_dataset(dataset):
|
||||
outputs = {
|
||||
"center": dataset["location"]["center"],
|
||||
"initialZoom": dataset["location"]["initialZoom"],
|
||||
"name": dataset["name"],
|
||||
"imageMetadata": dataset["imagery_metadata"],
|
||||
"url": dataset["leafletTileLayer"]["url"],
|
||||
"kwargs": str(dataset["leafletTileLayer"]["args"]).replace("True","true").replace("False","false"),
|
||||
"shapes": str([
|
||||
{"name": shape_layer["name"], "shapes_fn": shape_layer["shapes_fn"], "zone_name_key": shape_layer["zone_name_key"]} for shape_layer in dataset["shape_layers"]
|
||||
]).replace("None", "null") if dataset["shape_layers"] is not None else "null"
|
||||
}
|
||||
|
||||
if "wms" in dataset["leafletTileLayer"] and dataset["leafletTileLayer"]["wms"]:
|
||||
return '''{{
|
||||
"location": [{center}, {initialZoom}, "{name}", "{imageMetadata}"],
|
||||
"tileObject": L.tileLayer.wms("{url}", {kwargs}),
|
||||
"shapes": {shapes}
|
||||
}}'''.format(**outputs)
|
||||
else:
|
||||
return '''{{
|
||||
"location": [{center}, {initialZoom}, "{name}", "{imageMetadata}"],
|
||||
"tileObject": L.tileLayer("{url}", {kwargs}),
|
||||
"shapes": {shapes}
|
||||
}}'''.format(**outputs)
|
||||
|
||||
|
||||
|
||||
'''When this file is loaded we should load each dataset
|
||||
'''
|
||||
for dataset_key, dataset in DATASET_DEFINITIONS.items():
|
||||
|
||||
javascript_string = ""
|
||||
|
||||
loaded = True
|
||||
def _load_dataset(dataset):
|
||||
# Step 1: load the shape layers
|
||||
shape_layers = {}
|
||||
|
||||
# Load shapes first
|
||||
if dataset["shape_layers"] is not None:
|
||||
for shape_layer in dataset["shape_layers"]:
|
||||
fn = os.path.join(ROOT_DIR, shape_layer["shapes_fn"])
|
||||
if dataset["shapeLayers"] is not None:
|
||||
for shape_layer in dataset["shapeLayers"]:
|
||||
fn = os.path.join(ROOT_DIR, shape_layer["shapesFn"])
|
||||
if os.path.exists(fn):
|
||||
shapes, areas, crs = load_geojson_as_list(fn)
|
||||
shapes, areas, crs = _load_geojson_as_list(fn)
|
||||
shape_layer["geoms"] = shapes
|
||||
shape_layer["areas"] = areas
|
||||
shape_layer["crs"] = crs["init"]
|
||||
shape_layer["crs"] = crs["init"] # TODO: will this break with fiona version; I think `.crs` will turn into a PyProj object
|
||||
shape_layers[shape_layer["name"]] = shape_layer
|
||||
else:
|
||||
print("WARNING: %s doesn't exist, this server will not be able to serve the '%s' dataset" % (fn, dataset_key))
|
||||
loaded = False
|
||||
return False # TODO: maybe we should make these errors more descriptive (explain why we can't load a dataset)
|
||||
|
||||
|
||||
# Check to see if data_fn exists
|
||||
if "data_fn" in dataset:
|
||||
fn = os.path.join(ROOT_DIR, dataset["data_fn"])
|
||||
# Step 2: make sure the dataLayer exists
|
||||
if dataset["dataLayer"]["type"] == "CUSTOM":
|
||||
fn = os.path.join(ROOT_DIR, dataset["dataLayer"]["path"])
|
||||
if not os.path.exists(fn):
|
||||
print("WARNING: %s doesn't exist, this server will not be able to serve the '%s' dataset" % (fn, dataset_key))
|
||||
loaded = False
|
||||
return False # TODO: maybe we should make these errors more descriptive (explain why we can't load a dataset)
|
||||
|
||||
|
||||
if loaded:
|
||||
if dataset["data_layer_type"] == DatasetTypes.CUSTOM:
|
||||
data_loader = DataLoaderCustom(dataset["data_fn"], shape_layers, dataset["data_padding"])
|
||||
elif dataset["data_layer_type"] == DatasetTypes.USA_LAYER:
|
||||
data_loader = DataLoaderUSALayer(shape_layers, dataset["data_padding"])
|
||||
elif dataset["data_layer_type"] == DatasetTypes.BASEMAP:
|
||||
data_loader = DataLoaderBasemap(dataset["data_url"], dataset["data_padding"])
|
||||
else:
|
||||
raise ValueError("DatasetType not recognized")
|
||||
|
||||
DATASETS[dataset_key] = {
|
||||
"data_loader": data_loader,
|
||||
"shape_layers": shape_layers,
|
||||
"javascript_string": get_javascript_string_from_dataset(dataset)
|
||||
}
|
||||
# Step 3: setup the appropriate DatasetLoader
|
||||
if dataset["dataLayer"]["type"] == "CUSTOM":
|
||||
data_loader = DataLoaderCustom(dataset["dataLayer"]["path"], shape_layers, dataset["dataLayer"]["padding"])
|
||||
elif dataset["dataLayer"]["type"] == "USA_LAYER":
|
||||
data_loader = DataLoaderUSALayer(shape_layers, dataset["dataLayer"]["padding"])
|
||||
elif dataset["dataLayer"]["type"] == "BASEMAP":
|
||||
data_loader = DataLoaderBasemap(dataset["dataLayer"]["path"], dataset["dataLayer"]["padding"])
|
||||
else:
|
||||
pass # we are missing some files needed to load this dataset
|
||||
return False # TODO: maybe we should make these errors more descriptive (explain why we can't load a dataset)
|
||||
|
||||
return {
|
||||
"data_loader": data_loader,
|
||||
"shape_layers": shape_layers,
|
||||
}
|
||||
|
||||
def load_datasets():
|
||||
dataset_json = json.load(open(os.path.join(ROOT_DIR,_DATASET_FN),"r"))
|
||||
datasets = dict()
|
||||
|
||||
for key, dataset in dataset_json.items():
|
||||
dataset_object = _load_dataset(dataset)
|
||||
|
||||
if dataset_object is False:
|
||||
print("WARNING: files are missing, we will not be able to server '%s' dataset" % (key))
|
||||
else:
|
||||
datasets[key] = dataset_object
|
||||
|
||||
return datasets
|
|
@ -1,671 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link rel="icon" href="favicon.ico">
|
||||
|
||||
<title>Microsoft AI for Earth</title>
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link href="css/leaflet.css" rel="stylesheet" />
|
||||
<link href="css/leaflet-slider.css" rel="stylesheet" />
|
||||
<link href="css/leaflet-sidebar.css" rel="stylesheet" />
|
||||
<link href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.css">
|
||||
<link href="css/noty.css" rel="stylesheet">
|
||||
|
||||
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="css/main.css" rel="stylesheet">
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
<div id="privacy" class="leaflet-container">
|
||||
<a href="https://privacy.microsoft.com/en-US/privacystatement" target="_blank">Privacy Statement</a>
|
||||
</div>
|
||||
|
||||
<div id="sidebar" class="sidebar">
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="sidebar-content">
|
||||
|
||||
<!-- Start of "home" tab -->
|
||||
<div class="sidebar-pane" id="home">
|
||||
<div style="text-align: center; margin-bottom:10px;" id="inputImages">
|
||||
<h3 id="lblModelInput">Model Input</h3>
|
||||
<img id="inputImage">
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-bottom:10px; width:100%;" id="exampleImages">
|
||||
<h3>Land Cover Predictions</h3>
|
||||
<div id="exampleImageList">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="text-align: left; margin-bottom:10px; width:100%; padding-left:30px;">
|
||||
<span>Name of zone: <input type="text" id="lblZoneName" placeholder="none selected"/></span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom:10px;">
|
||||
|
||||
<h3 style="text-align: center; margin-top:20px;">Correction type:</h3>
|
||||
<div style="padding-left:20px">
|
||||
<div id="classList">
|
||||
<div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Water" data-jscolor="{valueElement:null,value:'0000FF',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label class="selected"><input type="radio" name="radClasses" class="radNewClass" value="Water" checked><span class="className">Water</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Tree Canopy" data-jscolor="{valueElement:null,value:'008000',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label><input type="radio" name="radClasses" class="radNewClass" value="Tree Canopy"><span class="className">Tree Canopy</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Field" data-jscolor="{valueElement:null,value:'80FF80',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label><input type="radio" name="radClasses" class="radNewClass" value="Field"><span class="className">Field</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Built" data-jscolor="{valueElement:null,value:'806060',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label><input type="radio" name="radClasses" class="radNewClass" value="Built"><span class="className">Built</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top:10px; margin-bottom:20px;">
|
||||
<button id="btnNewClass" style="background-color: gray; border-color: white;"> Add new class</button>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top:10px;">
|
||||
<button id="btnRetrain">Retrain (<span id="label-retrains">0</span> times)</button>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top:10px;">
|
||||
<button id="btnUndo">Undo</button>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top:10px;">
|
||||
<button id="btnReset">Reset</button>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top:10px;">
|
||||
<button id="btnDownload">Download</button>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top:10px;">
|
||||
<input type="text" id="lblURL" value="" placeholder="Visit this URL to start from a saved checkpoint" readonly="readonly"/>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin-top:5px;">
|
||||
<div id="lblPNG"></div>
|
||||
<div id="lblTIFF"></div>
|
||||
<div id="lblStatistics"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End of "home" tab -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Core JavaScript
|
||||
================================================== -->
|
||||
<script src="js/jquery-3.3.1.min.js"></script>
|
||||
<script src="js/noty.js" type="text/javascript"></script>
|
||||
<script src="js/jscolor.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Leaflet JavaScript
|
||||
================================================== -->
|
||||
<script src="js/leaflet.js" type="text/javascript"></script>
|
||||
<script src="js/leaflet-slider.js" type="text/javascript"></script>
|
||||
<script src="js/leaflet-sidebar.min.js" type="text/javascript"></script>
|
||||
<script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js" type="text/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.js" type="text/javascript"></script>
|
||||
|
||||
<!-- Application JavaScript
|
||||
================================================== -->
|
||||
<script src="js/main.js" type="text/javascript"></script>
|
||||
<script src="js/utils.js" type="text/javascript"></script>
|
||||
<script src="js/datasets.js" type="text/javascript"></script>
|
||||
<script src="js/globals.js" type="text/javascript"></script>
|
||||
|
||||
<!-- List of backend URLS to query
|
||||
================================================== -->
|
||||
<script src="endpoints.mine.js" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//'use strict';
|
||||
|
||||
var forEachFeatureOnClickCustom = function(feature, layer) {
|
||||
console.debug("Adding layer click");
|
||||
layer.on('click', function (e) {
|
||||
currentZone = layer;
|
||||
for(k in zoneMaps){
|
||||
zoneMaps[k].setStyle(defaultZoneStyle(zoneMapsWeight[k]));
|
||||
}
|
||||
layer.setStyle(highlightedZoneStyle);
|
||||
layer.bringToFront();
|
||||
var nameKey = e.target.feature.properties["KEY"];
|
||||
if (nameKey !== null){
|
||||
$("#lblZoneName").val(e.target.feature.properties[nameKey]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
BASEMAP_TO_DATASET_MAP = {
|
||||
"NAIP 2010": "florida_keys_2010_wmts",
|
||||
"NAIP 2013": "florida_keys_2013_wmts",
|
||||
"NAIP 2015": "florida_keys_2015_wmts"
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Runtime entrance
|
||||
//----------------------------------------------------------------------
|
||||
$(document).ready(function(){
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Remove the default behavior of the shift key
|
||||
//----------------------------------------------------------------------
|
||||
document.getElementById("map").onselectstart = function() {
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Parse URL arguments
|
||||
//----------------------------------------------------------------------
|
||||
let args = getURLArguments()
|
||||
EXP_NAME = args.userID
|
||||
BACKEND_URL = BACKEND_ENDPOINTS[0]["url"];
|
||||
DATASET = "florida_keys_2010_wmts"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Get a session id to include in all API requests
|
||||
//----------------------------------------------------------------------
|
||||
SESSION_ID = getRandomString(10);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Load the dataset specific shapes
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if(tileLayers[DATASET]["shapes"] !== null){
|
||||
for(zoneSetId in tileLayers[DATASET]["shapes"]){
|
||||
console.debug("Zonesetid", zoneSetId);
|
||||
var zoneName = tileLayers[DATASET]["shapes"][zoneSetId]["name"];
|
||||
zoneMapsWeight[zoneName] = defaultZoneLineWeights[zoneSetId];
|
||||
zoneMaps[zoneName] = L.geoJSON(null, {
|
||||
style: defaultZoneStyle(zoneMapsWeight[zoneName]),
|
||||
onEachFeature: forEachFeatureOnClickCustom,
|
||||
pane: "polygons"
|
||||
});
|
||||
getZoneMap(zoneSetId, zoneName, tileLayers[DATASET]["shapes"][zoneSetId]["shapes_fn"]);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup map layers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
var esriLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
|
||||
maxZoom: 20,
|
||||
maxNativeZoom: 17,
|
||||
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
})
|
||||
|
||||
var osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 20,
|
||||
maxNativeZoom: 17,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
})
|
||||
|
||||
var baseLayer = tileLayers[DATASET]["tileObject"];
|
||||
START_CENTER = tileLayers[DATASET]["location"][0];
|
||||
START_ZOOM = tileLayers[DATASET]["location"][1];
|
||||
|
||||
var initialLayers = [baseLayer];
|
||||
if(tileLayers[DATASET]["shapes"] !== null){
|
||||
initialLayers.push(zoneMaps[tileLayers[DATASET]["shapes"][0]["name"]]);
|
||||
currentZoneLayerName = tileLayers[DATASET]["shapes"][0]["name"];
|
||||
}
|
||||
|
||||
map = L.map('map', {
|
||||
zoomControl: false,
|
||||
crs: L.CRS.EPSG3857, // this is a default, but I'm setting it to be explicit about what CRS we are in
|
||||
center: START_CENTER,
|
||||
zoom: START_ZOOM,
|
||||
keyboard: false,
|
||||
minZoom: baseLayer.options.minZoom,
|
||||
layers: initialLayers
|
||||
});
|
||||
map.createPane('polygons');
|
||||
map.getPane('polygons').style.zIndex = 2000;
|
||||
|
||||
map.createPane('labels');
|
||||
map.getPane('labels').style.zIndex = 201;
|
||||
|
||||
map.createPane('downloadOutput');
|
||||
map.getPane('downloadOutput').style.zIndex = 200;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup layer picker
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
var baseMapString = tileLayers[DATASET]["location"][3];
|
||||
currentBasemapLayerName = baseMapString;
|
||||
|
||||
var baseMaps = {};
|
||||
baseMaps[baseMapString] = baseLayer;
|
||||
baseMaps["NAIP 2013"] = tileLayers["florida_keys_2013_wmts"]["tileObject"];
|
||||
baseMaps["NAIP 2015"] = tileLayers["florida_keys_2015_wmts"]["tileObject"];
|
||||
baseMaps["OpenStreetMap"] = osmLayer;
|
||||
baseMaps["'Google Earth' like Imagery"] = esriLayer;
|
||||
|
||||
|
||||
|
||||
var basemapLayerControl = L.control.layers(
|
||||
baseMaps, null, {
|
||||
collapsed:false,
|
||||
position:"bottomleft"
|
||||
}
|
||||
).addTo(map);
|
||||
|
||||
var basemapLayerControlContainer = basemapLayerControl.getContainer();
|
||||
|
||||
var zoneControl = L.control.layers(
|
||||
zoneMaps, null, {
|
||||
collapsed:false,
|
||||
position:"bottomleft"
|
||||
}
|
||||
).addTo(map);
|
||||
|
||||
var zoneControlContainer = zoneControl.getContainer();
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Setup AI4E Branding
|
||||
//----------------------------------------------------------------------
|
||||
var logoControl = $("<div class='leaflet-control logo-area'></div>");
|
||||
logoControl.append("<span class='logo-text'>Microsoft AI for Earth</span>");
|
||||
logoControl.append("<br/>");
|
||||
logoControl.append("<span class='logo-text-small'>Version: 0.9</span>");
|
||||
logoControl.append("<br/>");
|
||||
logoControl.append("<span class='logo-text-small'>Location: "+tileLayers[DATASET]["location"][2]+"</span>");
|
||||
|
||||
$(".leaflet-top.leaflet-left").append(logoControl)
|
||||
|
||||
$("#lblModelInput").html(tileLayers[DATASET]["location"][3]);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Custom initialization of the map zoom controls so that we can
|
||||
// position it where we want
|
||||
//----------------------------------------------------------------------
|
||||
L.control.zoom({
|
||||
position:'topleft'
|
||||
}).addTo(map);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup the leaflet-easybutton plugin to reset the map to its initial
|
||||
// position
|
||||
//----------------------------------------------------------------------
|
||||
L.easyButton(
|
||||
'fa-undo', function(btn, map) {
|
||||
map.closePopup();
|
||||
map.setView(START_CENTER, START_ZOOM);
|
||||
},
|
||||
).addTo(map);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup leaflet-slider plugin
|
||||
// First slider is to control map opacity
|
||||
//----------------------------------------------------------------------
|
||||
opacitySlider = L.control.slider( // opacity slider
|
||||
function(value){
|
||||
map.getPane('labels').style.opacity = value / 100.0;
|
||||
}, {
|
||||
position: 'bottomleft',
|
||||
id: 'opacity_slider',
|
||||
orientation: 'horizontal',
|
||||
collapsed: true,
|
||||
syncSlider: true,
|
||||
min: 0,
|
||||
max: 100,
|
||||
value: 100,
|
||||
logo: "Opacity",
|
||||
size: "171px"
|
||||
}
|
||||
);
|
||||
opacitySlider.addTo(map);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup the selection window size slider
|
||||
//----------------------------------------------------------------------
|
||||
windowSizeSlider = L.control.slider( // opacity slider
|
||||
function(value){
|
||||
SELECTION_SIZE = value;
|
||||
}, {
|
||||
position: 'bottomleft',
|
||||
id: 'window_size_slider',
|
||||
orientation: 'horizontal',
|
||||
collapsed: true,
|
||||
syncSlider: true,
|
||||
min: 10,
|
||||
max: 700,
|
||||
value: 300,
|
||||
logo: "Window Size",
|
||||
size: "171px"
|
||||
}
|
||||
);
|
||||
windowSizeSlider.addTo(map);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup the sharpness slider to control which type of image is shown
|
||||
//----------------------------------------------------------------------
|
||||
L.control.slider( // sharpness slider
|
||||
function(value){
|
||||
soft0_hard1 = value;
|
||||
|
||||
for(idx=0; idx<currentPatches.length; idx++){
|
||||
var tActiveImgIdx = currentPatches[idx]["activeImgIdx"];
|
||||
var srcs = currentPatches[idx]["patches"][tActiveImgIdx]["srcs"];
|
||||
currentPatches[idx]["imageLayer"].setUrl(srcs[soft0_hard1]);
|
||||
}
|
||||
|
||||
if(currentPatches.length>0){
|
||||
var idx = currentPatches.length - 1;
|
||||
for(var tActiveImgIdx=0; tActiveImgIdx<currentPatches[idx]["patches"].length; tActiveImgIdx++){
|
||||
var srcs = currentPatches[idx]["patches"][tActiveImgIdx]["srcs"];
|
||||
$("#exampleImage_"+tActiveImgIdx).attr("src", srcs[soft0_hard1]);
|
||||
}
|
||||
}
|
||||
|
||||
}, {
|
||||
position: 'bottomleft',
|
||||
id: 'soft_hard_slider',
|
||||
orientation: 'horizontal',
|
||||
collapsed: true,
|
||||
syncSlider: true,
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: 1,
|
||||
logo: "Sharpness",
|
||||
size: "171px"
|
||||
}
|
||||
).addTo(map);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup leaflet-sidebar-v2 and open the "#home" tab
|
||||
//----------------------------------------------------------------------
|
||||
var sidebar = L.control.sidebar(
|
||||
'sidebar', {
|
||||
position: 'right'
|
||||
}
|
||||
).addTo(map);
|
||||
sidebar.open("home")
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup map selection handlers
|
||||
//----------------------------------------------------------------------
|
||||
map.addEventListener('mousemove', function(e){
|
||||
// Choose style
|
||||
var curSelPoly = null;
|
||||
if(!shiftKeyDown){
|
||||
curSelPoly = getPolyAround(e.latlng, CORRECTION_SIZE);
|
||||
}else{
|
||||
curSelPoly = getPolyAround(e.latlng, SELECTION_SIZE);
|
||||
}
|
||||
|
||||
if(selectionBox === null){
|
||||
selectionBox = L.polygon(curSelPoly, {
|
||||
color: "#000000",
|
||||
fillColor: "#ffffff",
|
||||
weight: 2
|
||||
});
|
||||
selectionBox.addTo(map);
|
||||
}else{
|
||||
if(!animating){
|
||||
selectionBox.setStyle({
|
||||
color: "#000000",
|
||||
fillColor: "#ffffff",
|
||||
weight: 2
|
||||
});
|
||||
}
|
||||
selectionBox.setLatLngs(curSelPoly);
|
||||
}
|
||||
});
|
||||
|
||||
map.addEventListener('click', function(e){
|
||||
|
||||
var curSelPoly = null;
|
||||
if(shiftKeyDown){
|
||||
// Run the inference path
|
||||
curSelPoly = getPolyAround(e.latlng, SELECTION_SIZE);
|
||||
if(currentSelection === null){ // This condition creates the red selection box on the first click
|
||||
currentSelection = L.polygon(curSelPoly, {
|
||||
color: "#ff0000",
|
||||
fillColor: "#ffffff",
|
||||
weight: 2
|
||||
});
|
||||
currentSelection.addTo(map);
|
||||
}else{
|
||||
currentSelection.setLatLngs(curSelPoly);
|
||||
}
|
||||
|
||||
requestPatches(curSelPoly);
|
||||
}else{
|
||||
// Run the add sample path
|
||||
if(currentSelection !== null){
|
||||
if(isPointInsidePolygon(e.latlng, currentSelection)){
|
||||
if(currentBasemapLayerName == tileLayers[DATASET]["location"][3]){
|
||||
curSelPoly = getPolyAround(e.latlng, CORRECTION_SIZE);
|
||||
var idx = currentPatches.length-1;
|
||||
doSendCorrection(curSelPoly, idx);
|
||||
|
||||
var rect = L.rectangle(
|
||||
[curSelPoly[0], curSelPoly[2]],
|
||||
{
|
||||
color: classes[selectedClassIdx]["color"],
|
||||
weight: 1,
|
||||
opacity: 1
|
||||
//pane: "labels"
|
||||
}
|
||||
).addTo(map);
|
||||
userPointList.push([rect, selectedClassIdx]);
|
||||
|
||||
map.dragging.disable();
|
||||
numClicks += 1
|
||||
window.setTimeout(function(){
|
||||
numClicks -= 1;
|
||||
if(numClicks == 0){
|
||||
map.dragging.enable();
|
||||
}
|
||||
}, 700);
|
||||
}else{
|
||||
notifyFailMessage("Please add corrections using the '"+tileLayers[DATASET]["location"][3]+"' imagery layer.")
|
||||
}
|
||||
}else{
|
||||
console.debug("Click not in selection 123");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
map.on('contextmenu',function(e){}); // disables the context menu
|
||||
map.on('dblclick',function(e){});
|
||||
map.doubleClickZoom.disable();
|
||||
map.boxZoom.disable();
|
||||
|
||||
$(zoneControlContainer).find('input[type=radio]').change(function() {
|
||||
var name = $(this).siblings()[0].innerHTML.trim();
|
||||
currentZoneLayerName = name;
|
||||
console.debug("Switched zone layer to: " + name);
|
||||
});
|
||||
|
||||
$(basemapLayerControlContainer).find('input[type=radio]').change(function() {
|
||||
var name = $(this).siblings()[0].innerHTML.trim();
|
||||
currentBasemapLayerName = name;
|
||||
if(currentBasemapLayerName in BASEMAP_TO_DATASET_MAP){
|
||||
console.debug("Swapping dataset");
|
||||
DATASET = BASEMAP_TO_DATASET_MAP[currentBasemapLayerName];
|
||||
}
|
||||
console.debug("Switched basemap layer to: " + name);
|
||||
});
|
||||
|
||||
|
||||
$(document).keydown(function(e){
|
||||
shiftKeyDown = e.shiftKey;
|
||||
ctrlKeyDown = e.ctrlKey;
|
||||
});
|
||||
$(document).keyup(function(e){
|
||||
shiftKeyDown = e.shiftKey;
|
||||
ctrlKeyDown = e.ctrlKey;
|
||||
});
|
||||
|
||||
$(document).keydown(function(e) {
|
||||
if(document.activeElement == document.body){
|
||||
if(e.which == 97 || e.which == 65) { // "a"
|
||||
visible = false;
|
||||
map.getPane('labels').style.opacity = 0.0;
|
||||
opacitySlider.slider.value = 0;
|
||||
opacitySlider._updateValue();
|
||||
} else if(e.which == 115 || e.which == 83) { // "s"
|
||||
if(visible){
|
||||
visible = false;
|
||||
map.getPane('labels').style.opacity = 0.0;
|
||||
opacitySlider.slider.value = 0;
|
||||
opacitySlider._updateValue();
|
||||
}else{
|
||||
visible = true;
|
||||
map.getPane('labels').style.opacity = 1.0;
|
||||
opacitySlider.slider.value = 100;
|
||||
opacitySlider._updateValue();
|
||||
}
|
||||
} else if(e.which == 100 || e.which == 68) { "d"
|
||||
visible = true;
|
||||
map.getPane('labels').style.opacity = 1.0;
|
||||
opacitySlider.slider.value = 100
|
||||
opacitySlider._updateValue();
|
||||
} else if((e.which == 114 || e.which == 82) && !ctrlKeyDown){ "r"
|
||||
doRetrain();
|
||||
} else if(e.which == 37){ "left arrow"
|
||||
var currentOpacity = parseFloat(map.getPane('labels').style.opacity);
|
||||
if (currentOpacity >= 0.05){
|
||||
currentOpacity -= 0.05;
|
||||
|
||||
map.getPane('labels').style.opacity = currentOpacity;
|
||||
opacitySlider.slider.value = currentOpacity*100;
|
||||
opacitySlider._updateValue();
|
||||
}
|
||||
e.preventDefault()
|
||||
} else if(e.which == 39){ "right arrow"
|
||||
var currentOpacity = parseFloat(map.getPane('labels').style.opacity);
|
||||
if (currentOpacity <= 0.95){
|
||||
currentOpacity += 0.05;
|
||||
|
||||
map.getPane('labels').style.opacity = currentOpacity;
|
||||
opacitySlider.slider.value = currentOpacity*100;
|
||||
opacitySlider._updateValue();
|
||||
}
|
||||
e.preventDefault()
|
||||
} else if(e.which == 38 || e.which == 40){
|
||||
e.preventDefault()
|
||||
} else if(ctrlKeyDown && e.which==90){
|
||||
doUndo();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#btnRetrain").click(doRetrain);
|
||||
$("#btnUndo").click(doUndo);
|
||||
$("#btnReset").click(function(){doReset(true, initialReset=false)});
|
||||
$("#btnDownload").click(doDownloadTile);
|
||||
$("#btnNewClass").click(function(){
|
||||
|
||||
var newClassIdx = classes.length + 1;
|
||||
var newColor = getRandomColor();
|
||||
|
||||
var newClassElement = $("<div class='radio'>");
|
||||
var newLabel = $("<label><input type='radio' name='radClasses' class='radNewClass' value='Class "+newClassIdx+"'><span class='className'>Class "+newClassIdx+"</span> (<span class='classCounts'>0</span> samples since last retrain)<i class='fa fa-edit ml-1 classNameEdit'></i></label>");
|
||||
|
||||
var newPicker = document.createElement('button');
|
||||
newPicker.classList.add("circle");
|
||||
newPicker.classList.add("jscolor");
|
||||
newPicker.setAttribute("data-class-name", "Class "+newClassIdx);
|
||||
var output = new jscolor(newPicker, {
|
||||
valueElement: null,
|
||||
value: newColor.substr(1),
|
||||
position:'left',
|
||||
zIndex:2001,
|
||||
closable:true,
|
||||
closeText:'Close',
|
||||
onFineChange:'updateClassColor(this)'
|
||||
});
|
||||
|
||||
newClassElement.append(newPicker);
|
||||
newClassElement.append(newLabel);
|
||||
|
||||
$("#classList").append(newClassElement);
|
||||
|
||||
classes.push({
|
||||
"name": "Class " + newClassIdx,
|
||||
"color": newColor,
|
||||
"count": 0
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup radio button change detection
|
||||
//----------------------------------------------------------------------
|
||||
$(document).on('change', '.radNewClass', function(){
|
||||
|
||||
$('.radio label').removeClass("selected");
|
||||
$(this).parent().addClass("selected");
|
||||
|
||||
selectedClassIdx = findClassByName(this.value);
|
||||
console.debug(this.value + " " + selectedClassIdx);
|
||||
});
|
||||
|
||||
$(document).on('click', '.classNameEdit', function(){
|
||||
var oldName = $(this).siblings(".className").html();
|
||||
var newName = prompt("New label name for '"+oldName+"'");
|
||||
$(this).siblings(".className").html(newName);
|
||||
$(this).siblings(".radNewClass").val(newName);
|
||||
|
||||
$(this).parent().siblings(".jscolor").attr("data-class-name", newName);
|
||||
|
||||
var classIdx = findClassByName(oldName)
|
||||
classes[classIdx]["name"] = newName;
|
||||
|
||||
|
||||
});
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup the example images list
|
||||
//----------------------------------------------------------------------
|
||||
for(var i=0; i<ENDPOINTS.length; i++){
|
||||
var img = $("<img class='exampleImage'>");
|
||||
img.attr("im-id", i);
|
||||
img.attr("id", "exampleImage_"+i);
|
||||
$("#exampleImageList").append(img);
|
||||
}
|
||||
|
||||
$(".exampleImage").click(function(){
|
||||
$(".exampleImage").removeClass("active");
|
||||
$(this).addClass("active");
|
||||
|
||||
var idx = currentPatches.length-1;
|
||||
activeImgIdx = $(this).attr("im-id");
|
||||
|
||||
var srcs = currentPatches[idx]["patches"][activeImgIdx]["srcs"];
|
||||
currentPatches[idx]["imageLayer"].setUrl(srcs[soft0_hard1]);
|
||||
currentPatches[idx]["activeImgIdx"] = activeImgIdx;
|
||||
$(this).attr("src", srcs[soft0_hard1]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -4,7 +4,7 @@ var DATASET = null;
|
|||
var START_CENTER = null;
|
||||
var START_ZOOM = null;
|
||||
|
||||
var SELECTION_SIZE = 300; // in meters, probably
|
||||
var SELECTION_SIZE = 300; // number of units (meters) in EPSG:3857 (the number of _actual_ meters this represents will vary based on latitute)
|
||||
var CORRECTION_SIZE = 1;
|
||||
|
||||
var SESSION_ID = null;
|
||||
|
|
|
@ -241,7 +241,7 @@ var getZoneMap = function(zoneSetId, name, url){
|
|||
url: url,
|
||||
success: function(data) {
|
||||
for(k in data.features){
|
||||
data.features[k].properties["KEY"] = tileLayers[DATASET]["shapes"][zoneSetId]["zone_name_key"];
|
||||
data.features[k].properties["KEY"] = DATASETS[DATASET]["shapeLayers"][zoneSetId]["zoneNameKey"];
|
||||
}
|
||||
zoneMaps[name].addData(data);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,6 @@
|
|||
================================================== -->
|
||||
<script src="js/main.js" type="text/javascript"></script>
|
||||
<script src="js/utils.js" type="text/javascript"></script>
|
||||
<script src="js/datasets.js" type="text/javascript"></script>
|
||||
<script src="js/globals.js" type="text/javascript"></script>
|
||||
|
||||
<!-- List of backend URLS to query
|
||||
|
@ -135,7 +134,22 @@
|
|||
<script src="endpoints.mine.js" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//'use strict';
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Load potential datasets
|
||||
//----------------------------------------------------------------------
|
||||
var DATASETS = (function () {
|
||||
var json = null;
|
||||
$.ajax({
|
||||
'async': false,
|
||||
'url': 'data/datasets.json',
|
||||
'dataType': "json",
|
||||
'success': function(data){
|
||||
json = data;
|
||||
}
|
||||
});
|
||||
return json;
|
||||
})();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Runtime entrance
|
||||
|
@ -157,7 +171,7 @@
|
|||
EXP_NAME = args.userID
|
||||
BACKEND_URL = BACKEND_ENDPOINTS[args.backendID]["url"];
|
||||
|
||||
if(!(args.dataset in tileLayers) && (args.dataset !== null)){
|
||||
if(!(args.dataset in DATASETS) && (args.dataset !== null)){
|
||||
args.dataset = null;
|
||||
new Noty({
|
||||
type: "error",
|
||||
|
@ -196,16 +210,18 @@
|
|||
// Load the dataset specific shapes
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if(tileLayers[DATASET]["shapes"] !== null){
|
||||
for(zoneSetId in tileLayers[DATASET]["shapes"]){
|
||||
if(DATASETS[DATASET]["shapeLayers"] !== null){
|
||||
for(zoneSetId in DATASETS[DATASET]["shapeLayers"]){
|
||||
console.debug("Zonesetid", zoneSetId);
|
||||
var zoneName = tileLayers[DATASET]["shapes"][zoneSetId]["name"];
|
||||
var zoneName = DATASETS[DATASET]["shapeLayers"][zoneSetId]["name"];
|
||||
zoneMapsWeight[zoneName] = defaultZoneLineWeights[zoneSetId];
|
||||
zoneMaps[zoneName] = L.geoJSON(null, {
|
||||
style: defaultZoneStyle(zoneMapsWeight[zoneName]),
|
||||
onEachFeature: forEachFeatureOnClick
|
||||
onEachFeature: forEachFeatureOnClick,
|
||||
pane: "polygons"
|
||||
});
|
||||
getZoneMap(zoneSetId, zoneName, tileLayers[DATASET]["shapes"][zoneSetId]["shapes_fn"]);
|
||||
|
||||
getZoneMap(zoneSetId, zoneName, DATASETS[DATASET]["shapeLayers"][zoneSetId]["shapesFn"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,11 +235,6 @@
|
|||
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
})
|
||||
|
||||
// var esriLayer = L.tileLayer('http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', {
|
||||
// maxZoom: 20,
|
||||
// subdomains:['mt0','mt1','mt2','mt3']
|
||||
// });
|
||||
|
||||
var osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 20,
|
||||
maxNativeZoom: 17,
|
||||
|
@ -231,19 +242,19 @@
|
|||
})
|
||||
|
||||
|
||||
if((DATASET != "esri_world_imagery") && (DATASET != "esri_world_imagery_naip")){
|
||||
interestingLocations = [];
|
||||
}
|
||||
var baseLayer = tileLayers[DATASET]["tileObject"];
|
||||
START_CENTER = tileLayers[DATASET]["location"][0];
|
||||
START_ZOOM = tileLayers[DATASET]["location"][1];
|
||||
var baseLayer = L.tileLayer(DATASETS[DATASET]["basemapLayer"]["url"], DATASETS[DATASET]["basemapLayer"]["args"]);
|
||||
|
||||
|
||||
START_CENTER = DATASETS[DATASET]["basemapLayer"]["initialLocation"];
|
||||
START_ZOOM = DATASETS[DATASET]["basemapLayer"]["initialZoom"];
|
||||
|
||||
interestingLocations = []
|
||||
var cities = L.layerGroup(interestingLocations);
|
||||
|
||||
var initialLayers = [baseLayer];
|
||||
if(tileLayers[DATASET]["shapes"] !== null){
|
||||
initialLayers.push(zoneMaps[tileLayers[DATASET]["shapes"][0]["name"]]);
|
||||
currentZoneLayerName = tileLayers[DATASET]["shapes"][0]["name"];
|
||||
if(DATASETS[DATASET]["shapeLayers"] !== null){
|
||||
initialLayers.push(zoneMaps[DATASETS[DATASET]["shapeLayers"][0]["name"]]);
|
||||
currentZoneLayerName = DATASETS[DATASET]["shapeLayers"][0]["name"];
|
||||
}
|
||||
|
||||
map = L.map('map', {
|
||||
|
@ -255,6 +266,9 @@
|
|||
minZoom: baseLayer.options.minZoom,
|
||||
layers: initialLayers
|
||||
});
|
||||
map.createPane('polygons');
|
||||
map.getPane('polygons').style.zIndex = 2000;
|
||||
|
||||
map.createPane('labels');
|
||||
map.getPane('labels').style.zIndex = 201;
|
||||
|
||||
|
@ -271,7 +285,7 @@
|
|||
// Setup layer picker
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
var baseMapString = tileLayers[DATASET]["location"][3];
|
||||
var baseMapString = DATASETS[DATASET]["metadata"]["imageryName"];
|
||||
currentBasemapLayerName = baseMapString;
|
||||
|
||||
var baseMaps = {};
|
||||
|
@ -305,11 +319,11 @@
|
|||
logoControl.append("<br/>");
|
||||
logoControl.append("<span class='logo-text-small'>Version: 0.9</span>");
|
||||
logoControl.append("<br/>");
|
||||
logoControl.append("<span class='logo-text-small'>Location: "+tileLayers[DATASET]["location"][2]+"</span>");
|
||||
logoControl.append("<span class='logo-text-small'>Location: "+DATASETS[DATASET]["metadata"]["displayName"]+"</span>");
|
||||
|
||||
$(".leaflet-top.leaflet-left").append(logoControl)
|
||||
|
||||
$("#lblModelInput").html(tileLayers[DATASET]["location"][3]);
|
||||
$("#lblModelInput").html(DATASETS[DATASET]["metadata"]["locationName"]);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Custom initialization of the map zoom controls so that we can
|
||||
|
@ -471,7 +485,7 @@
|
|||
// Run the add sample path
|
||||
if(currentSelection !== null){
|
||||
if(isPointInsidePolygon(e.latlng, currentSelection)){
|
||||
if(currentBasemapLayerName == tileLayers[DATASET]["location"][3]){
|
||||
if(currentBasemapLayerName == DATASETS[DATASET]["location"][3]){
|
||||
curSelPoly = getPolyAround(e.latlng, CORRECTION_SIZE);
|
||||
var idx = currentPatches.length-1;
|
||||
doSendCorrection(curSelPoly, idx);
|
||||
|
@ -496,7 +510,7 @@
|
|||
}
|
||||
}, 700);
|
||||
}else{
|
||||
notifyFailMessage("Please add corrections using the '"+tileLayers[DATASET]["location"][3]+"' imagery layer.")
|
||||
notifyFailMessage("Please add corrections using the '"+DATASETS[DATASET]["location"][3]+"' imagery layer.")
|
||||
}
|
||||
}else{
|
||||
console.debug("Click not in selection");
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
</div>
|
||||
|
||||
<div style="text-align: left; margin-bottom:10px; width:100%; padding-left:30px;">
|
||||
<span>Name of zone: <input type="text" id="lblZoneName" placeholder="none selected"/></span>
|
||||
<span>Name of zone: <span id="lblZoneName">none selected</span></span>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom:10px;">
|
||||
|
@ -127,7 +127,6 @@
|
|||
================================================== -->
|
||||
<script src="js/main.js" type="text/javascript"></script>
|
||||
<script src="js/utils.js" type="text/javascript"></script>
|
||||
<script src="js/datasets.js" type="text/javascript"></script>
|
||||
<script src="js/globals.js" type="text/javascript"></script>
|
||||
|
||||
<!-- List of backend URLS to query
|
||||
|
@ -135,39 +134,22 @@
|
|||
<script src="endpoints.mine.js" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//'use strict';
|
||||
|
||||
var forEachFeatureOnClickCustom = function(feature, layer) {
|
||||
console.debug("Adding layer click");
|
||||
layer.on('click', function (e) {
|
||||
currentZone = layer;
|
||||
for(k in zoneMaps){
|
||||
zoneMaps[k].setStyle(defaultZoneStyle(zoneMapsWeight[k]));
|
||||
}
|
||||
layer.setStyle(highlightedZoneStyle);
|
||||
layer.bringToFront();
|
||||
var nameKey = e.target.feature.properties["KEY"];
|
||||
if (nameKey !== null){
|
||||
$("#lblZoneName").val(e.target.feature.properties[nameKey]);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Load potential datasets
|
||||
//----------------------------------------------------------------------
|
||||
var DATASETS = (function () {
|
||||
var json = null;
|
||||
$.ajax({
|
||||
'async': false,
|
||||
'url': 'data/datasets.json',
|
||||
'dataType': "json",
|
||||
'success': function(data){
|
||||
json = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var defaultZoneLineWeights = [
|
||||
0.5,1,0.7,0.3
|
||||
]
|
||||
|
||||
BASEMAP_TO_DATASET_MAP = {
|
||||
"NAIP 2010": "la_coast_2010_wmts",
|
||||
"NAIP 2013": "la_coast_2013_wmts",
|
||||
"NAIP 2015": "la_coast_2015_wmts",
|
||||
"NLCD Ground Truth Old": "la_coast_nlcd_wmts",
|
||||
"NLCD Ground Truth 2011": "la_coast_nlcd_2011_wmts",
|
||||
"NLCD Ground Truth 2013": "la_coast_nlcd_2013_wmts",
|
||||
"NLCD Ground Truth 2016": "la_coast_nlcd_2016_wmts",
|
||||
"Embedded NLCD 2010": "la_coast_embed_2010_wmts",
|
||||
"Embedded NLCD 2013": "la_coast_embed_2013_wmts"
|
||||
}
|
||||
return json;
|
||||
})();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Runtime entrance
|
||||
|
@ -187,29 +169,59 @@
|
|||
//----------------------------------------------------------------------
|
||||
let args = getURLArguments()
|
||||
EXP_NAME = args.userID
|
||||
BACKEND_URL = BACKEND_ENDPOINTS[0]["url"];
|
||||
DATASET = "la_coast_2010_wmts"
|
||||
BACKEND_URL = BACKEND_ENDPOINTS[args.backendID]["url"];
|
||||
|
||||
if(!(args.dataset in DATASETS) && (args.dataset !== null)){
|
||||
args.dataset = null;
|
||||
new Noty({
|
||||
type: "error",
|
||||
text: "Requested dataset doesn't exist, using default",
|
||||
layout: 'topCenter',
|
||||
timeout: 5000,
|
||||
theme: 'metroui'
|
||||
}).show();
|
||||
}
|
||||
if(args.dataset === null){
|
||||
args.dataset = "esri_world_imagery";
|
||||
}
|
||||
DATASET = args.dataset;
|
||||
|
||||
if(args.cachedModel !== null){
|
||||
doLoad(args.cachedModel); // load a cached version of the model
|
||||
}else{
|
||||
doReset(false, true); // reset the backend server
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Get a session id to include in all API requests
|
||||
//----------------------------------------------------------------------
|
||||
SESSION_ID = getRandomString(10);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Start user study if necessary
|
||||
//----------------------------------------------------------------------
|
||||
var userStudy = false;
|
||||
if(args.maxTime !== null){
|
||||
runUserStudyTimer(args.maxTime);
|
||||
userStudy = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Load the dataset specific shapes
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
if(tileLayers[DATASET]["shapes"] !== null){
|
||||
for(zoneSetId in tileLayers[DATASET]["shapes"]){
|
||||
if(DATASETS[DATASET]["shapeLayers"] !== null){
|
||||
for(zoneSetId in DATASETS[DATASET]["shapeLayers"]){
|
||||
console.debug("Zonesetid", zoneSetId);
|
||||
var zoneName = tileLayers[DATASET]["shapes"][zoneSetId]["name"];
|
||||
var zoneName = DATASETS[DATASET]["shapeLayers"][zoneSetId]["name"];
|
||||
zoneMapsWeight[zoneName] = defaultZoneLineWeights[zoneSetId];
|
||||
zoneMaps[zoneName] = L.geoJSON(null, {
|
||||
style: defaultZoneStyle(zoneMapsWeight[zoneName]),
|
||||
onEachFeature: forEachFeatureOnClickCustom,
|
||||
onEachFeature: forEachFeatureOnClick,
|
||||
pane: "polygons"
|
||||
});
|
||||
getZoneMap(zoneSetId, zoneName, tileLayers[DATASET]["shapes"][zoneSetId]["shapes_fn"]);
|
||||
|
||||
getZoneMap(zoneSetId, zoneName, DATASETS[DATASET]["shapeLayers"][zoneSetId]["shapesFn"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,20 +235,34 @@
|
|||
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
})
|
||||
|
||||
var custom1 = L.tileLayer('tiles/atimur_healthy_veg/{z}/{x}/{y}.png', {
|
||||
tms: true,
|
||||
minZoom: 8,
|
||||
maxNativeZoom: 16,
|
||||
maxZoom: 20,
|
||||
attribution: 'Georeferenced Image'
|
||||
});
|
||||
|
||||
var osmLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 20,
|
||||
maxNativeZoom: 17,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
})
|
||||
|
||||
var baseLayer = tileLayers[DATASET]["tileObject"];
|
||||
START_CENTER = tileLayers[DATASET]["location"][0];
|
||||
START_ZOOM = tileLayers[DATASET]["location"][1];
|
||||
|
||||
|
||||
var baseLayer = L.tileLayer(DATASETS[DATASET]["basemapLayer"]["url"], DATASETS[DATASET]["basemapLayer"]["args"]);
|
||||
|
||||
|
||||
START_CENTER = DATASETS[DATASET]["basemapLayer"]["initialLocation"];
|
||||
START_ZOOM = DATASETS[DATASET]["basemapLayer"]["initialZoom"];
|
||||
|
||||
interestingLocations = []
|
||||
var cities = L.layerGroup(interestingLocations);
|
||||
|
||||
var initialLayers = [baseLayer];
|
||||
if(tileLayers[DATASET]["shapes"] !== null){
|
||||
initialLayers.push(zoneMaps[tileLayers[DATASET]["shapes"][0]["name"]]);
|
||||
currentZoneLayerName = tileLayers[DATASET]["shapes"][0]["name"];
|
||||
if(DATASETS[DATASET]["shapeLayers"] !== null){
|
||||
initialLayers.push(zoneMaps[DATASETS[DATASET]["shapeLayers"][0]["name"]]);
|
||||
currentZoneLayerName = DATASETS[DATASET]["shapeLayers"][0]["name"];
|
||||
}
|
||||
|
||||
map = L.map('map', {
|
||||
|
@ -257,23 +283,22 @@
|
|||
map.createPane('downloadOutput');
|
||||
map.getPane('downloadOutput').style.zIndex = 200;
|
||||
|
||||
for(var i=0;i<interestingLocations.length;i++){
|
||||
interestingLocations[i].on('click', function(e){
|
||||
map.setView(e.latlng, 13);
|
||||
});
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup layer picker
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
var baseMapString = tileLayers[DATASET]["location"][3];
|
||||
var baseMapString = DATASETS[DATASET]["metadata"]["imageryName"];
|
||||
currentBasemapLayerName = baseMapString;
|
||||
|
||||
var baseMaps = {};
|
||||
baseMaps[baseMapString] = baseLayer;
|
||||
baseMaps["NAIP 2013"] = tileLayers["la_coast_2013_wmts"]["tileObject"];
|
||||
baseMaps["NAIP 2015"] = tileLayers["la_coast_2015_wmts"]["tileObject"];
|
||||
baseMaps["NLCD Ground Truth Old"] = tileLayers["la_coast_nlcd_wmts"]["tileObject"];
|
||||
baseMaps["NLCD Ground Truth 2011"] = tileLayers["la_coast_nlcd_2011_wmts"]["tileObject"];
|
||||
baseMaps["NLCD Ground Truth 2013"] = tileLayers["la_coast_nlcd_2013_wmts"]["tileObject"];
|
||||
baseMaps["NLCD Ground Truth 2016"] = tileLayers["la_coast_nlcd_2016_wmts"]["tileObject"];
|
||||
baseMaps["Embedded NLCD 2010"] = tileLayers["la_coast_embed_2010_wmts"]["tileObject"];
|
||||
baseMaps["Embedded NLCD 2013"] = tileLayers["la_coast_embed_2013_wmts"]["tileObject"];
|
||||
baseMaps["Healthy Vegetation"] = custom1;
|
||||
baseMaps["OpenStreetMap"] = osmLayer;
|
||||
baseMaps["'Google Earth' like Imagery"] = esriLayer;
|
||||
|
||||
|
@ -303,11 +328,11 @@
|
|||
logoControl.append("<br/>");
|
||||
logoControl.append("<span class='logo-text-small'>Version: 0.9</span>");
|
||||
logoControl.append("<br/>");
|
||||
logoControl.append("<span class='logo-text-small'>Location: "+tileLayers[DATASET]["location"][2]+"</span>");
|
||||
logoControl.append("<span class='logo-text-small'>Location: "+DATASETS[DATASET]["metadata"]["displayName"]+"</span>");
|
||||
|
||||
$(".leaflet-top.leaflet-left").append(logoControl)
|
||||
|
||||
$("#lblModelInput").html(tileLayers[DATASET]["location"][3]);
|
||||
$("#lblModelInput").html(DATASETS[DATASET]["metadata"]["locationName"]);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Custom initialization of the map zoom controls so that we can
|
||||
|
@ -469,7 +494,7 @@
|
|||
// Run the add sample path
|
||||
if(currentSelection !== null){
|
||||
if(isPointInsidePolygon(e.latlng, currentSelection)){
|
||||
if(currentBasemapLayerName == tileLayers[DATASET]["location"][3]){
|
||||
if(currentBasemapLayerName == DATASETS[DATASET]["location"][3]){
|
||||
curSelPoly = getPolyAround(e.latlng, CORRECTION_SIZE);
|
||||
var idx = currentPatches.length-1;
|
||||
doSendCorrection(curSelPoly, idx);
|
||||
|
@ -494,10 +519,10 @@
|
|||
}
|
||||
}, 700);
|
||||
}else{
|
||||
notifyFailMessage("Please add corrections using the '"+tileLayers[DATASET]["location"][3]+"' imagery layer.")
|
||||
notifyFailMessage("Please add corrections using the '"+DATASETS[DATASET]["location"][3]+"' imagery layer.")
|
||||
}
|
||||
}else{
|
||||
console.debug("Click not in selection 123");
|
||||
console.debug("Click not in selection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -517,10 +542,6 @@
|
|||
$(basemapLayerControlContainer).find('input[type=radio]').change(function() {
|
||||
var name = $(this).siblings()[0].innerHTML.trim();
|
||||
currentBasemapLayerName = name;
|
||||
if(currentBasemapLayerName in BASEMAP_TO_DATASET_MAP){
|
||||
console.debug("Swapping dataset");
|
||||
DATASET = BASEMAP_TO_DATASET_MAP[currentBasemapLayerName];
|
||||
}
|
||||
console.debug("Switched basemap layer to: " + name);
|
||||
});
|
||||
|
|
@ -34,7 +34,10 @@ from azure.cosmosdb.table.models import Entity
|
|||
|
||||
from DataLoader import warp_data_to_3857, crop_data_by_extent
|
||||
from Heatmap import Heatmap
|
||||
from Datasets import DATASETS
|
||||
|
||||
from Datasets import load_datasets
|
||||
DATASETS = load_datasets()
|
||||
|
||||
from Utils import get_random_string, class_prediction_to_img, get_shape_layer_by_name, AtomicCounter
|
||||
|
||||
from ServerModelsKerasDense import KerasDenseFineTune
|
||||
|
@ -405,7 +408,7 @@ def pred_tile():
|
|||
img_hard = cv2.cvtColor(img_hard, cv2.COLOR_RGB2BGRA)
|
||||
img_hard[nodata_mask] = [0,0,0,0]
|
||||
|
||||
img_hard, img_hard_bounds = warp_data_to_3857(img_hard, raster_crs, raster_transform, raster_bounds, resolution=1)
|
||||
img_hard, img_hard_bounds = warp_data_to_3857(img_hard, raster_crs, raster_transform, raster_bounds, resolution=10)
|
||||
|
||||
cv2.imwrite(os.path.join(ROOT_DIR, "downloads/%s.png" % (tmp_id)), img_hard)
|
||||
data["downloadPNG"] = "downloads/%s.png" % (tmp_id)
|
||||
|
@ -497,29 +500,6 @@ def get_input_metadata():
|
|||
def get_root_app():
|
||||
return bottle.static_file("index.html", root="./" + ROOT_DIR + "/")
|
||||
|
||||
def get_datasets():
|
||||
tile_layers = "var tileLayers = {\n"
|
||||
for dataset_name, dataset in DATASETS.items():
|
||||
tile_layers += '"%s": %s,\n' % (dataset_name, dataset["javascript_string"])
|
||||
tile_layers += "};"
|
||||
|
||||
interesting_locations = '''var interestingLocations = [
|
||||
L.marker([47.60, -122.15]).bindPopup('Bellevue, WA'),
|
||||
L.marker([39.74, -104.99]).bindPopup('Denver, CO'),
|
||||
L.marker([37.53, -77.44]).bindPopup('Richmond, VA'),
|
||||
L.marker([39.74, -104.99]).bindPopup('Denver, CO'),
|
||||
L.marker([37.53, -77.44]).bindPopup('Richmond, VA'),
|
||||
L.marker([33.746526, -84.387522]).bindPopup('Atlanta, GA'),
|
||||
L.marker([32.774250, -96.796122]).bindPopup('Dallas, TX'),
|
||||
L.marker([40.106675, -88.236409]).bindPopup('Champaign, IL'),
|
||||
L.marker([38.679485, -75.874667]).bindPopup('Dorchester County, MD'),
|
||||
L.marker([34.020618, -118.464412]).bindPopup('Santa Monica, CA'),
|
||||
L.marker([37.748517, -122.429771]).bindPopup('San Fransisco, CA'),
|
||||
L.marker([38.601951, -98.329227]).bindPopup('Ellsworth County, KS')
|
||||
];'''
|
||||
|
||||
return tile_layers + '\n\n' + interesting_locations
|
||||
|
||||
def get_favicon():
|
||||
return
|
||||
|
||||
|
@ -625,7 +605,6 @@ def main():
|
|||
app.route("/heatmap/<z>/<y>/<x>", method="GET", callback=do_heatmap)
|
||||
|
||||
app.route("/", method="GET", callback=get_root_app)
|
||||
app.route("/js/datasets.js", method="GET", callback=get_datasets)
|
||||
app.route("/favicon.ico", method="GET", callback=get_favicon)
|
||||
app.route("/<filepath:re:.*>", method="GET", callback=get_everything_else)
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ def main():
|
|||
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
args.batch_size = 10
|
||||
args.num_epochs = 10
|
||||
args.num_epochs = 30
|
||||
|
||||
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
||||
os.environ["CUDA_VISIBLE_DEVICES"] = str(args.gpuid)
|
||||
|
@ -162,14 +162,15 @@ def main():
|
|||
num_classes = 64
|
||||
data_original_shape = data.shape
|
||||
data_color_features = data.reshape(-1,data_original_shape[2])
|
||||
kmeans = MiniBatchKMeans(n_clusters=num_classes, verbose=1, compute_labels=False)
|
||||
kmeans = kmeans.fit(data_color_features)
|
||||
mask = (data_color_features == 0).sum(axis=1) != data_original_shape[2]
|
||||
kmeans = MiniBatchKMeans(n_clusters=num_classes, verbose=1, init_size=2**16, n_init=20, batch_size=2**14, compute_labels=False)
|
||||
kmeans = kmeans.fit(data_color_features[mask])
|
||||
#labels = kmeans.fit_predict(data_color_features)
|
||||
labels = manual_kmeans_predict(data_color_features, cluster_centers=kmeans.cluster_centers_)
|
||||
data_color_labels = labels.reshape(data_original_shape[:2])
|
||||
|
||||
print("Extracting training samples")
|
||||
n_samples = 4000
|
||||
n_samples = 5000
|
||||
height, width = 150, 150
|
||||
x_all = np.zeros((n_samples, height, width, data_original_shape[2]), dtype=np.float32)
|
||||
y_all = np.zeros((n_samples, height, width), dtype=np.float32)
|
||||
|
@ -178,12 +179,17 @@ def main():
|
|||
x = np.random.randint(0, data.shape[1]-width)
|
||||
y = np.random.randint(0, data.shape[0]-height)
|
||||
|
||||
while np.any((data[y:y+height, x:x+width, :] == 0).sum(axis=2) == data_original_shape[2]):
|
||||
x = np.random.randint(0, data.shape[1]-width)
|
||||
y = np.random.randint(0, data.shape[0]-height)
|
||||
|
||||
img = data[y:y+height, x:x+width, :].astype(np.float32)
|
||||
target = data_color_labels[y:y+height, x:x+width].copy()
|
||||
|
||||
x_all[i] = img
|
||||
y_all[i] = target
|
||||
|
||||
del data, data_color_labels, data_color_features
|
||||
x_all = x_all/255.0
|
||||
y_all = keras.utils.to_categorical(y_all, num_classes=num_classes)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче