Loading jupyter/examples/Example.ipynb +86 −153 File changed.Preview size limit exceeded, changes collapsed. Show changes jupyter/src/CartoCosmos.py +213 −146 Original line number Diff line number Diff line Loading @@ -5,12 +5,15 @@ import json import geojson import shapely.geometry as geo import shapely.wkt import os import urllib.request class planetary_maps: def __init__(self, targetName): self.target_name = targetName self.json_file = 'geoServerLayers.json' self.base_layers = [] self.layers = [] self.planet_map = None self.map_layers = { 'base': [], Loading @@ -25,9 +28,22 @@ class planetary_maps: self.gui = planetary_gui() self.dmajor_radius = 0 self.dminor_radius = 0 # Variables to keep track of how many times handle_feature_click is called. # There is a bug where it is called twice, the first time passing in feature # and the second time passing in the coordinates. We need both of those variables self.handle_feature_click_counter = 0 self.handle_feature_click_feature = None self.json_dict = None dir_path = os.path.dirname(os.path.realpath(__file__)) with open(dir_path + "/geoServerLayers.json", 'r') as fp: self.json_dict = json.load(fp) self.find_radius() self.create_layers() self.create_map() self.feature_collection = { 'type': 'FeatureCollection', 'features': [] Loading @@ -35,22 +51,19 @@ class planetary_maps: def find_radius(self): with open(self.json_file, 'r') as fp: json_dict = json.load(fp) targets = json_dict['targets'] targets = self.json_dict['targets'] for i, target in enumerate(targets): current_target = targets[i] if current_target['name'].lower() == self.target_name: self.dmajor_radius = float(current_target['aaxisradius']) * 1000.0 self.dminor_radius = float(current_target['caxisradius']) * 1000.0 break; self.dmajor_radius = float( current_target['aaxisradius']) * 1000.0 self.dminor_radius = float( current_target['caxisradius']) * 1000.0 break def create_layers(self): with open(self.json_file, 'r') as fp: json_dict = json.load(fp) targets = json_dict['targets'] targets = self.json_dict['targets'] for i, target in enumerate(targets): current_target = targets[i] if current_target['name'].lower() == self.target_name: Loading @@ -61,19 +74,36 @@ class planetary_maps: if current_layer['transparent'] == 'false': self.map_layers['base'].append(current_layer) else: if current_layer['displayname'] == "Show Feature Names": continue self.map_layers['overlays'].append(current_layer) for layer in self.map_layers['base']: if layer['projection'] == 'cylindrical': wms_layer = WMSLayer( url='https://planetarymaps.usgs.gov/cgi-bin/mapserv?map=' + layer['map'], url=layer["url"] + "?map=" + layer["map"], layers=layer['layer'], name=layer['displayname'], crs='EPSG4326', base=True, show_loading=False, ) self.layers.append(wms_layer) for layer in self.map_layers['overlays']: if layer['projection'] == 'cylindrical': wms_layer = WMSLayer( url=layer["url"] + "?map=" + layer["map"], layers=layer['layer'], name=layer['displayname'], crs='EPSG4326', base=True base=False, transparent=True, format="image/png", show_loading=False, visible=False, ) self.base_layers.append(wms_layer) self.layers.append(wms_layer) def handle_interaction(self, **kwargs): if kwargs.get('type') == 'mousemove': Loading @@ -94,26 +124,27 @@ class planetary_maps: lng = -180 + (abs(lng) % 180) if self.gui.get_longitude_range().value == "0 to 360": lng += 180; lng += 180 if self.gui.get_lat_domain().value == "Planetographic": converted_latitude = Math.radians(lat) converted_latitude = Math.atan(((self.dmajor_radius / self.dminor_radius)**2) * (Math.tan(converted_latitude))) converted_latitude = Math.atan( ((self.dmajor_radius / self.dminor_radius)**2) * (Math.tan(converted_latitude))) converted_latitude = Math.degrees(converted_latitude) lat = converted_latitude if self.gui.get_longitude_direction().value == "Positive West": if(self.gui.get_longitude_range().value == "-180 to 180"): lng *= -1 else: lng = Math.fabs(lng - 360) self.gui.get_lat_lon_label().value = "Lat, Lon: "+ str(round(lat, 2)) + ", " + str(round(lng, 2)) self.gui.get_lat_lon_label().value = "Lat, Lon: " + \ str(round(lat, 2)) + ", " + str(round(lng, 2)) def create_map(self): self.planet_map = Map(layers=tuple(self.base_layers), center=(0, 0), zoom=1, crs='EPSG4326') self.planet_map = Map(layers=tuple(self.layers), center=(0, 0), zoom=1, crs='EPSG4326') draw_control = DrawControl() draw_control.polyline = { Loading Loading @@ -156,10 +187,14 @@ class planetary_maps: draw_control.on_draw(self.handle_draw) self.gui.get_wkt_button().on_click(self.handle_WKT_button) self.range_control = WidgetControl(widget=self.gui.get_longitude_range(), position='topright') self.lat_control = WidgetControl(widget=self.gui.get_lat_domain(), position='topright') self.direction_control = WidgetControl(widget=self.gui.get_longitude_direction(), position='topright') self.label_control = WidgetControl(widget=self.gui.get_lat_lon_label(), position='bottomright') self.range_control = WidgetControl( widget=self.gui.get_longitude_range(), position='topright') self.lat_control = WidgetControl( widget=self.gui.get_lat_domain(), position='topright') self.direction_control = WidgetControl( widget=self.gui.get_longitude_direction(), position='topright') self.label_control = WidgetControl( widget=self.gui.get_lat_lon_label(), position='bottomright') self.planet_map.add_control(draw_control) self.planet_map.add_control(LayersControl(position='topright')) Loading @@ -168,8 +203,6 @@ class planetary_maps: self.planet_map.add_control(fullscreen_control) self.planet_map.on_interaction(self.handle_fullscreen) def display_map(self): display(self.gui.get_longitude_range()) display(self.gui.get_lat_domain()) Loading @@ -180,17 +213,19 @@ class planetary_maps: display(self.gui.get_wkt_text_box()) display(self.gui.get_wkt_button()) # Display map first, then add features self.add_wfs_features() def add_wkt(self, wktString): try: g1 = shapely.wkt.loads(wktString) g2 = geojson.Feature(geometry=g1, properties={}) geo_json = GeoJSON(data=g2, style = {'color': 'yellow', 'opacity':1, 'weight':1.9, 'fillOpacity':0.5}) geo_json = GeoJSON(data=g2, style={ 'color': 'yellow', 'opacity': 1, 'weight': 1.9, 'fillOpacity': 0.5}) self.planet_map.add_layer(geo_json) except: self.gui.get_wkt_text_box().value = "Invalid WKT String" def handle_draw(self, *args, **kwargs): """Do something with the GeoJSON when it's drawn on the map""" geo_json = kwargs.get('geo_json') Loading Loading @@ -220,6 +255,51 @@ class planetary_maps: def handle_WKT_button(self, *args, **kwargs): self.add_wkt(self.gui.get_wkt_text_box().value) def add_wfs_features(self): geoJsonUrl = ("https://astrocloud.wr.usgs.gov/dataset/data/nomenclature/{}/WFS?" "service=WFS&version=1.1.0&request=GetFeature&outputFormat=application%2Fjson" "&srsName=EPSG%3A4326".format(self.target_name.upper())) break_out = False while not break_out: try: # Try until no 404 error is thrown by server with urllib.request.urlopen(geoJsonUrl, timeout=240) as url: jsonp = json.loads(url.read()) # Sort features by diameter jsonp['features'] = sorted( jsonp['features'], key=lambda feature: feature["properties"]["diameter"]) geo_json = GeoJSON(data=jsonp, name="Show Feature Names") geo_json.point_style = { 'fillOpacity': 1, 'radius': 3 } geo_json.on_click(self.handle_feature_click) self.planet_map.add_layer(geo_json) break_out = True except: continue def handle_feature_click(self, feature=None, coordinates=None, **kwargs): self.handle_feature_click_counter += 1 if self.handle_feature_click_counter == 1: self.handle_feature_click_feature = feature elif self.handle_feature_click_counter == 2: popup = Popup( location=coordinates, child=widgets.HTML(self.handle_feature_click_feature['name']), close_button=True, auto_close=True, close_on_escape_key=False ) self.planet_map.add_layer(popup) self.handle_feature_click_counter = 0 return class planetary_gui: def __init__(self): self.longitude_range = None Loading Loading @@ -294,16 +374,3 @@ class planetary_gui: def get_longitude_range(self): return self.longitude_range Loading
jupyter/examples/Example.ipynb +86 −153 File changed.Preview size limit exceeded, changes collapsed. Show changes
jupyter/src/CartoCosmos.py +213 −146 Original line number Diff line number Diff line Loading @@ -5,12 +5,15 @@ import json import geojson import shapely.geometry as geo import shapely.wkt import os import urllib.request class planetary_maps: def __init__(self, targetName): self.target_name = targetName self.json_file = 'geoServerLayers.json' self.base_layers = [] self.layers = [] self.planet_map = None self.map_layers = { 'base': [], Loading @@ -25,9 +28,22 @@ class planetary_maps: self.gui = planetary_gui() self.dmajor_radius = 0 self.dminor_radius = 0 # Variables to keep track of how many times handle_feature_click is called. # There is a bug where it is called twice, the first time passing in feature # and the second time passing in the coordinates. We need both of those variables self.handle_feature_click_counter = 0 self.handle_feature_click_feature = None self.json_dict = None dir_path = os.path.dirname(os.path.realpath(__file__)) with open(dir_path + "/geoServerLayers.json", 'r') as fp: self.json_dict = json.load(fp) self.find_radius() self.create_layers() self.create_map() self.feature_collection = { 'type': 'FeatureCollection', 'features': [] Loading @@ -35,22 +51,19 @@ class planetary_maps: def find_radius(self): with open(self.json_file, 'r') as fp: json_dict = json.load(fp) targets = json_dict['targets'] targets = self.json_dict['targets'] for i, target in enumerate(targets): current_target = targets[i] if current_target['name'].lower() == self.target_name: self.dmajor_radius = float(current_target['aaxisradius']) * 1000.0 self.dminor_radius = float(current_target['caxisradius']) * 1000.0 break; self.dmajor_radius = float( current_target['aaxisradius']) * 1000.0 self.dminor_radius = float( current_target['caxisradius']) * 1000.0 break def create_layers(self): with open(self.json_file, 'r') as fp: json_dict = json.load(fp) targets = json_dict['targets'] targets = self.json_dict['targets'] for i, target in enumerate(targets): current_target = targets[i] if current_target['name'].lower() == self.target_name: Loading @@ -61,19 +74,36 @@ class planetary_maps: if current_layer['transparent'] == 'false': self.map_layers['base'].append(current_layer) else: if current_layer['displayname'] == "Show Feature Names": continue self.map_layers['overlays'].append(current_layer) for layer in self.map_layers['base']: if layer['projection'] == 'cylindrical': wms_layer = WMSLayer( url='https://planetarymaps.usgs.gov/cgi-bin/mapserv?map=' + layer['map'], url=layer["url"] + "?map=" + layer["map"], layers=layer['layer'], name=layer['displayname'], crs='EPSG4326', base=True, show_loading=False, ) self.layers.append(wms_layer) for layer in self.map_layers['overlays']: if layer['projection'] == 'cylindrical': wms_layer = WMSLayer( url=layer["url"] + "?map=" + layer["map"], layers=layer['layer'], name=layer['displayname'], crs='EPSG4326', base=True base=False, transparent=True, format="image/png", show_loading=False, visible=False, ) self.base_layers.append(wms_layer) self.layers.append(wms_layer) def handle_interaction(self, **kwargs): if kwargs.get('type') == 'mousemove': Loading @@ -94,26 +124,27 @@ class planetary_maps: lng = -180 + (abs(lng) % 180) if self.gui.get_longitude_range().value == "0 to 360": lng += 180; lng += 180 if self.gui.get_lat_domain().value == "Planetographic": converted_latitude = Math.radians(lat) converted_latitude = Math.atan(((self.dmajor_radius / self.dminor_radius)**2) * (Math.tan(converted_latitude))) converted_latitude = Math.atan( ((self.dmajor_radius / self.dminor_radius)**2) * (Math.tan(converted_latitude))) converted_latitude = Math.degrees(converted_latitude) lat = converted_latitude if self.gui.get_longitude_direction().value == "Positive West": if(self.gui.get_longitude_range().value == "-180 to 180"): lng *= -1 else: lng = Math.fabs(lng - 360) self.gui.get_lat_lon_label().value = "Lat, Lon: "+ str(round(lat, 2)) + ", " + str(round(lng, 2)) self.gui.get_lat_lon_label().value = "Lat, Lon: " + \ str(round(lat, 2)) + ", " + str(round(lng, 2)) def create_map(self): self.planet_map = Map(layers=tuple(self.base_layers), center=(0, 0), zoom=1, crs='EPSG4326') self.planet_map = Map(layers=tuple(self.layers), center=(0, 0), zoom=1, crs='EPSG4326') draw_control = DrawControl() draw_control.polyline = { Loading Loading @@ -156,10 +187,14 @@ class planetary_maps: draw_control.on_draw(self.handle_draw) self.gui.get_wkt_button().on_click(self.handle_WKT_button) self.range_control = WidgetControl(widget=self.gui.get_longitude_range(), position='topright') self.lat_control = WidgetControl(widget=self.gui.get_lat_domain(), position='topright') self.direction_control = WidgetControl(widget=self.gui.get_longitude_direction(), position='topright') self.label_control = WidgetControl(widget=self.gui.get_lat_lon_label(), position='bottomright') self.range_control = WidgetControl( widget=self.gui.get_longitude_range(), position='topright') self.lat_control = WidgetControl( widget=self.gui.get_lat_domain(), position='topright') self.direction_control = WidgetControl( widget=self.gui.get_longitude_direction(), position='topright') self.label_control = WidgetControl( widget=self.gui.get_lat_lon_label(), position='bottomright') self.planet_map.add_control(draw_control) self.planet_map.add_control(LayersControl(position='topright')) Loading @@ -168,8 +203,6 @@ class planetary_maps: self.planet_map.add_control(fullscreen_control) self.planet_map.on_interaction(self.handle_fullscreen) def display_map(self): display(self.gui.get_longitude_range()) display(self.gui.get_lat_domain()) Loading @@ -180,17 +213,19 @@ class planetary_maps: display(self.gui.get_wkt_text_box()) display(self.gui.get_wkt_button()) # Display map first, then add features self.add_wfs_features() def add_wkt(self, wktString): try: g1 = shapely.wkt.loads(wktString) g2 = geojson.Feature(geometry=g1, properties={}) geo_json = GeoJSON(data=g2, style = {'color': 'yellow', 'opacity':1, 'weight':1.9, 'fillOpacity':0.5}) geo_json = GeoJSON(data=g2, style={ 'color': 'yellow', 'opacity': 1, 'weight': 1.9, 'fillOpacity': 0.5}) self.planet_map.add_layer(geo_json) except: self.gui.get_wkt_text_box().value = "Invalid WKT String" def handle_draw(self, *args, **kwargs): """Do something with the GeoJSON when it's drawn on the map""" geo_json = kwargs.get('geo_json') Loading Loading @@ -220,6 +255,51 @@ class planetary_maps: def handle_WKT_button(self, *args, **kwargs): self.add_wkt(self.gui.get_wkt_text_box().value) def add_wfs_features(self): geoJsonUrl = ("https://astrocloud.wr.usgs.gov/dataset/data/nomenclature/{}/WFS?" "service=WFS&version=1.1.0&request=GetFeature&outputFormat=application%2Fjson" "&srsName=EPSG%3A4326".format(self.target_name.upper())) break_out = False while not break_out: try: # Try until no 404 error is thrown by server with urllib.request.urlopen(geoJsonUrl, timeout=240) as url: jsonp = json.loads(url.read()) # Sort features by diameter jsonp['features'] = sorted( jsonp['features'], key=lambda feature: feature["properties"]["diameter"]) geo_json = GeoJSON(data=jsonp, name="Show Feature Names") geo_json.point_style = { 'fillOpacity': 1, 'radius': 3 } geo_json.on_click(self.handle_feature_click) self.planet_map.add_layer(geo_json) break_out = True except: continue def handle_feature_click(self, feature=None, coordinates=None, **kwargs): self.handle_feature_click_counter += 1 if self.handle_feature_click_counter == 1: self.handle_feature_click_feature = feature elif self.handle_feature_click_counter == 2: popup = Popup( location=coordinates, child=widgets.HTML(self.handle_feature_click_feature['name']), close_button=True, auto_close=True, close_on_escape_key=False ) self.planet_map.add_layer(popup) self.handle_feature_click_counter = 0 return class planetary_gui: def __init__(self): self.longitude_range = None Loading Loading @@ -294,16 +374,3 @@ class planetary_gui: def get_longitude_range(self): return self.longitude_range