def make_arc(self, Pcenter, radius, start_angle=0.0, stop_angle=360.0, clockwiseArc=False): assert (isinstance(Pcenter, Point)) assert (isinstance(radius, float)) assert (isinstance(start_angle, float)) assert (isinstance(stop_angle, float)) if clockwiseArc and (start_angle < stop_angle): start_angle = start_angle + 360 if (not clockwiseArc) and (stop_angle < start_angle): stop_angle = stop_angle + 360 g = [] numsegments = self._getNbrSegment(radius) angles = np.linspace(start_angle, stop_angle, numsegments) polygon = geog.propagate(Pcenter, angles, radius) #print(json.dumps(mapping(Polygon(polygon)))) #print(json.dumps(mapping(LineString(polygon)))) for o in polygon: g.append([ round(o[0], self.oCtrl.digit4roundArc), round(o[1], self.oCtrl.digit4roundArc) ]) return g
def make_arc(self, Pcenter, radius, start_angle=0.0, stop_angle=360.0, clockwiseArc=False): assert(isinstance(Pcenter, Point)) assert(isinstance(radius, float)) assert(isinstance(start_angle, float)) assert(isinstance(stop_angle, float)) if clockwiseArc and (start_angle < stop_angle): start_angle = start_angle+360 if (not clockwiseArc) and (stop_angle < start_angle): stop_angle = stop_angle+360 g = [] numsegments = self._getNbrSegment(radius) angles = np.linspace(start_angle, stop_angle, numsegments) polygon = geog.propagate(Pcenter, angles, radius) ## #print(json.dumps(mapping(Polygon(polygon)))) ## #print(json.dumps(mapping(LineString(polygon)))) for o in polygon: g.append([round(o[0],self.oCtrl.geojsonDigitOptimize), round(o[1],self.oCtrl.geojsonDigitOptimize)]) #Other function - https://stackoverflow.com/questions/30762329/how-to-create-polygons-with-arcs-in-shapely-or-a-better-library #theta = np.radians(angles) #x = Pcenter.x + (radius * np.cos(theta)) #y = Pcenter.y + (radius * np.sin(theta)) #polygon = LineString(np.column_stack([x, y])) #for o in polygon.coords: # g.append([round(o[0],self.oCtrl.geojsonDigitOptimize), round(o[1],self.oCtrl.geojsonDigitOptimize)]) return g
def get_cell_ids_h3(lat: float, lng: float, angle: float) -> Set: p = shapely.geometry.Point([lng, lat]) # so to more accurately match projections maybe arc length of a sphere would be best? arc_length = R_MEAN * angle # in km n_points = 20 # arc_length should be in kilometers so convert to meters d = arc_length * 1000 # meters angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) try: mapping = shapely.geometry.mapping(shapely.geometry.Polygon(polygon)) except ValueError as e: print(f"lat:{lat}, lng:{lng}") print(polygon) cells = set() needs_split = False for point in polygon: if point[0] > 180 or point[0] < -180: needs_split = True break if needs_split: try: (first, second) = split_antimeridian_polygon(polygon) cells.update(h3.polyfill(first, H3_RESOLUTION_LEVEL, True)) cells.update(h3.polyfill(second, H3_RESOLUTION_LEVEL, True)) except: print(f"lat:{lat}, lng:{lng}") else: cells = h3.polyfill(mapping, H3_RESOLUTION_LEVEL, True) return cells
def test_prop_one_bearing(): loc = 'bos' a = 30 d = 5000 result = geog.propagate(locs[loc], a, d, bearing=True) assert np.allclose(result, _p[loc][60][d])
def lng_lat(lat, lngg): ''' Return points around a cretian area on a map :return: Two lists of lng and lat ''' global lng global latt lng = list() latt = list() p = shapely.geometry.Point([lat, lngg]) n_points = 10 d = random.randrange(100, 300) # meters angles = np.linspace(0, random.randrange(0, 360), n_points) polygon = geog.propagate(p, angles, d) all_points = json.dumps( shapely.geometry.mapping(shapely.geometry.Polygon(polygon))) print(all_points) x = json.loads(all_points) for i in range(n_points): # lng print(x['coordinates'][0][i][1]) # lat print(x['coordinates'][0][i][0]) lng.append(x['coordinates'][0][i][1]) latt.append(x['coordinates'][0][i][0]) return latt, lng
def test_prop_one(): loc = 'bos' a = 30 d = 5000 result = geog.propagate(locs[loc], a, d) assert len(result) == 2 # If it's a 2d array this will fail assert np.allclose(result, _p[loc][a][d])
def test_prop_n_d_to_one(): loc = locs['bos'] a = 30 ds = [5000, 100000] expected = [_p['bos'][a][d] for d in ds] result = geog.propagate(loc, a, ds) assert np.allclose(result, expected)
def test_prop_n_ang_to_one(): loc = locs['bos'] angles = [30, 60] d = 5000 expected = [_p['bos'][ang][d] for ang in angles] result = geog.propagate(loc, angles, d) assert np.allclose(result, expected)
def test_prop_n_loc_to_one(): tlocs = ['bos', 'dc', 'la'] a = 30 d = 5000 expected = [_p[loc][a][d] for loc in tlocs] coords = [locs[loc] for loc in tlocs] assert np.allclose(geog.propagate(coords, a, d), expected)
def test_prop_n_to_n(): tlocs = ['bos', 'dc', 'la'] angles = [60, 30, 30] ds = [5000, 100000, 5000] expected = [_p[loc][a][d] for (loc, a, d) in zip(tlocs, angles, ds)] coords = [locs[loc] for loc in tlocs] result = geog.propagate(coords, angles, ds)
def makebox(latitude, longitude, radius): p = Point([longitude, latitude]) angles = np.linspace(0, 360, 5) polygon = geog.propagate(p, angles, radius) box = Polygon(polygon).envelope gdf = gpd.GeoDataFrame(geometry=[box], crs='epsg:4326') bounds = [[min(gdf.geometry[0].exterior.coords.xy[1]), min(gdf.geometry[0].exterior.coords.xy[0])], [max(gdf.geometry[0].exterior.coords.xy[1]), max(gdf.geometry[0].exterior.coords.xy[0])]] return gdf, bounds
def gera_polygon_from_point(p,n,r): ''' Gera n pontos localizados ao redor de p com raio r metros. Exemplo de uso (20 pontos e raio de 1 km): p = shapely.geometry.Point([-90.0, 29.9]) n = 20 r = 1000 print(gera_polygon_from_point(p,n,r)) ''' angles = np.linspace(0, 360, n) polygon = geog.propagate(p, angles, r) return shapely.geometry.Polygon(polygon)
def circle_from_point(point, radius, nb_point=20): """ return a circle (shapely POLYGON) from a point parameters: - point: a shapely POINT - radius: circle's diameter in meter - nb_point: nb of point of the polygo, """ angles = np.linspace(0, 360, nb_point) polygon = geog.propagate(point, angles, radius) return Polygon(polygon)
def get_frost_polygon_2(lat, longtitude): #p = shapely.geometry.Point([9.071083834835958, 59.06658858430363]) p = shapely.geometry.Point([lat, longtitude]) n_points = 20 d = 1 * 4000 # meters angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) poly = Polygon(polygon) print( json.dumps(shapely.geometry.mapping( shapely.geometry.Polygon(polygon)))) return poly
def points_to_circle(gdfin, crcl_radius=100, number_of_points=10): """ Create circles which cover the relevant geometry for geographic coordinat """ angles = np.linspace(0, 360, number_of_points) circle_cord = [ geog.propagate(xy, angles, crcl_radius) for xy in zip(gdfin.geometry.x, gdfin.geometry.y) ] circle_geom = [ shapely.geometry.Polygon( zip(circle_cord[i][:, 0], circle_cord[i][:, 1])) for i in range(0, len(circle_cord)) ] gdfout = gdfin[:] gdfout.geometry = circle_geom return gdfout
def circular_grid(cntr_latlng, dim=50, min_cnt=50): lnglats = [(cntr_latlng[1], cntr_latlng[0])] d = dim n = 0 while len(lnglats) < min_cnt: c = d * 2 * math.pi n_points = int(math.floor(c / dim)) angles = np.linspace(0, 360, n_points) if n % 2 == 0: angles += 360.0 / n_points / 2.0 lnglats.extend(geog.propagate(lnglats[0], angles, d)) #print("{} \t {}".format(d,n_points)) d += dim n += 1 print("{} locations plotted to geojson.".format(len(lnglats))) feacoll = locs_to_geojson(lnglats) return feacoll
def create_circle(x, y, radius, n_points=360): p = geometry.Point([x, y]) n_points = 360 d = radius * 1000 angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) shape = json.dumps(geometry.mapping(geometry.Polygon(polygon))) shape = json.loads(shape) lon = list() lat = list() for coord in range(len(shape['coordinates'][0])): lon.append(shape['coordinates'][0][coord][0]) lat.append(shape['coordinates'][0][coord][1]) return (lon, lat)
def get_circle_from_point(lat, long, radius, n_points=20): """ Returns a circle around a lat/long point with given radius. :param lat: latitude of point :type lat: float :param long: longitude of point :type long: float :param radius: radius of the circle :type radius: float :param n_points: number of sides of the polygon :type n_points: int :return: circle (polygon) :rtype: shapely Polygon """ p = Point([long, lat]) angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, radius) return Polygon(polygon)
def get_frost_polygon(lat, longtitude): #p = shapely.geometry.Point([9.071083834835958, 59.06658858430363]) p = shapely.geometry.Point([lat, longtitude]) n_points = 20 d = 1 * 4000 # meters angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) #print(json.dumps(shapely.geometry.mapping(shapely.geometry.Polygon(polygon)))) x_fixed = ['{} {}'.format(x[0], x[1]) for x in polygon] li = ['{}' for x in x_fixed] res = "POLYGON(("+', '.join(li) + "))" res2 = res.format(*x_fixed) return res2
def geodataframe_basic(parameters: Parameters) -> pd.DataFrame: circle_code = parameters.parameters.get('CircleAbbrev', 'XXXX') latitude = parameters.parameters.get('CircleLatitude', None) longitude = parameters.parameters.get('CircleLongitude', None) geo_name = parameters.parameters.get('CircleName', circle_code) circle_center = geometry.Point([longitude, latitude]) # longitude first n_points = 20 angles = np.linspace(0, 360, n_points) polygon = geog.propagate(circle_center, angles, circle_radius) geom = geometry.Polygon(polygon) gdf = pd.DataFrame.from_records([{'CircleCode': circle_code, 'GeoName': geo_name, 'Description': 'Count Circle Boundary', 'geometry': geom, 'type': 'circle', 'source': 'parameters'}]) return gdf
def inscribed_polygon_from_circle(lon: float, lat: float, radius_in_m: float, n_edges: int): """ :param lon: :param lat: :param radius_in_m: :param n_edges: how many edges should the polygon have :return: """ center_point = shapely.geometry.Point([lon, lat]) # linspace accepts number of points so we add 1 to have the desired number of edges angles = np.linspace(0, 360, n_edges + 1) polygon = geog.propagate(center_point, angles, radius_in_m) result = shapely.geometry.mapping(shapely.geometry.Polygon(polygon)) return json.loads(json.dumps(result))
def compute_footprint(sat, date_time, alpha=None): """Compute the footprints of the Satellite at a given instance. :param sat: Satellite object :type sat: instance of the satnogs-collisions Satellite object :param date_time: desired date and time of the satellite footprint :type date_time: Python datetime object :param alpha: half angle given by user in degrees, defaults to None :type alpha: int, optional :return: Footprint of the Satllite in GeoJSON format :rtype: Shapely Polygon instance """ line1, line2, line3 = sat.get_tle( ) # Read TLE of the sateellite and create an Ephem instance sat = ephem.readtle(line1, line2, line3) sat.compute(date_time) sublat = sat.sublat # Sub-satellite points sublong = sat.sublong h = sat.elevation # height of the satellite above sea level in m d = None # Diameter of the circular coverage if alpha: theta = math.degrees(math.asin(sin(alpha) * (R / (R + h)))) - alpha theta = math.radians(theta) d = 2 * R * theta # diameter else: rho = math.degrees(math.asin( (R / (R + h)))) # Compute d as maximum d if alpha isn't defined lam = 90 - rho lam = math.radians(lam) d_max = R * (math.tan(lam)) d = d_max p = Point([sublat, sublong]) # Convert the data to GeoJSON format n = 32 angles = np.linspace(0, 360, n) polygon = geog.propagate(p, angles, d) footprint = Polygon(list(polygon)) return footprint
def get_cell_ids_h3(lat:float, lng:float, angle: float) -> List: p = shapely.geometry.Point([lng, lat]) # so to more accurately match projections maybe arc length of a sphere woulde be best? arc_length = R_MEAN * angle # in km n_points = 20 #arc_length should be the radius in kilometers so convert to diameter in meters d = arc_length * 1000 # meters angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) try: mapping = shapely.geometry.mapping(shapely.geometry.Polygon(polygon)) except ValueError as e: print(f"lat:{lat}, lng:{lng}") print(polygon) cells = h3.polyfill(mapping, H3_RESOLUTION_LEVEL, True) return cells
def pos2wkt(self, pos): """ Return Well Known Text representation of region defined by "pos" tuple :type pos: tuple :param pos: Definition of square region, size L m, region of interest centred on lon lat (lon, lat, L) :return: :wkt: *str* Well known text representation of pos """ # Unpack parameters lon = pos[0] lat = pos[1] size = pos[2] centre = shapely.geometry.Point([lat, lon]) angles = linspace(0, 360, 5) + 45.0 polygon = geog.propagate(centre, angles, (size**2 / 2.0)**0.5) return shapely.geometry.Polygon(polygon).wkt
def __init__(self, info): for name, data in info.items(): if name == 'geocode': self[name] = combine(data) elif name == 'areaDesc': self[name] = data elif name == 'polygon': self[name] = data if isinstance(data, str): if ' ' not in data: logger.error("Bad Polygon") return None self['location'] = Polygon(convertGeo(data)) elif isinstance(data, list): polydict = [] for poly in data: polydict.append(convertGeo(poly)) self['location'] = MultiPolygon(polydict) else: self['location'] = {'type': 'unsupported'} logger.error("Unsupported type of polygon area: {}".format( type(data))) elif name == 'circle': # <circle>51.507709,-99.233116 2.26</circle> # There is no GeoJSON Cicle types, thus needs to be converted to a polygon of sides circlePoint = data.split(' ')[0] circleSize = float(data.split(' ')[1]) * 1000 point = shapely.geometry.Point([ float(circlePoint.split(',')[1]), float(circlePoint.split(',')[0]) ]) angles = np.linspace(0, 360, 40) polygon = geog.propagate(point, angles, circleSize) self['location'] = shapely.geometry.mapping( shapely.geometry.Polygon(polygon)) else: logger.error("Unsupported Geo Type: {}".format(name))
def generate_points(pivot, radius, n_points=20): angles = np.linspace(0, 360, n_points) points = geog.propagate(pivot, angles, radius) return list(points)
def Variable_Radius(facilities, Malawi_pop, Max_Radius, Initial_Radius, Increment_Radius, Max_pop_in_circle, Year, crs={'init': 'epsg:4326'}): facilities.crs = crs Max_Radius = Max_Radius + Increment_Radius facilities['radius'] = Initial_Radius Flag = False columns = facilities.columns while True: facilities['cvrd_poly'] = facilities.apply(lambda row: Polygon( geog.propagate(row['geometry'], np.linspace(0, 360, 20), row[ 'radius'] * 1000)), axis=1) facilities = facilities.set_geometry('cvrd_poly') covered_pop_2020 = gpd.tools.sjoin(Malawi_pop, facilities, how='inner', op='intersects', lsuffix='map', rsuffix='fac') covered_pop_dissolve = covered_pop_2020[[ 'dvcl', '2020_pop_1', '2021_pop_1', '2022_pop_1', '2023_pop_1', 'geometry_map' ]] covered_pop_dissolve = gpd.GeoDataFrame(covered_pop_dissolve, crs=crs, geometry='geometry_map') covered_pop_dissolve = covered_pop_dissolve.dissolve(by='dvcl', aggfunc='sum', as_index=False) if Flag == True: facilities = pd.merge(facilities, covered_pop_dissolve.drop('geometry_map', axis=1), on='dvcl', how='left') Flag = False break check = pd.merge(facilities, covered_pop_dissolve.drop('geometry_map', axis=1), on='dvcl', how='left') check['radius'] = check.apply( lambda row: row['radius'] + Increment_Radius if row[Year + '_pop_1'] <= Max_pop_in_circle else row['radius'], axis=1) if check['radius'].max() == Max_Radius: facilities = pd.merge(facilities, covered_pop_dissolve.drop('geometry_map', axis=1), on='dvcl', how='left') facilities['radius'] = facilities.apply( lambda row: row['radius'] - Increment_Radius if row[Year + '_pop_1'] > Max_pop_in_circle else row['radius'], axis=1) facilities = facilities[columns] Flag = True continue check = check[facilities.columns] facilities = check return facilities
def storms_in_pol_map(year_st, year_en, lat=32.36, lon=-64.68, meters=185., name='BERMUDA'): """ Given latitude and longitude coordinates as well as a "radius" around the latitude and longitude coordinates, this function plots the tracks of storms that passed within a distance from the location. :param year_st: start of the period :param year_en: end of the period :param lat: latitude coordinate for location :param lon: longitude coordinate for location :param name: name of location for saving purposes :param meters: radius around location """ #25.761681, -80.191788 MIAMI #29.951065, -90.071533 # New Orleans x1 = lat # latitude of location if lon >0: y1 = lon else: y1 = 360. + lon # longitude of location # making the lat and lon coordinates of the location into a point p = shapely.geometry.Point([y1, x1]) # Creating a polygon around the location n_points = 100 # with 100 points d = meters * 1000 # meters, 185km = 100nm angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) POL = shapely.geometry.Polygon(polygon) # Lower and upper bounds for latitude and longitude used for the map llon = round(y1 - 10.) # lower bound for lon ulon = round(y1 + 10.) # upper bound for lon llat = round(x1 - 10.) # lower bound for lat ulat = round(x1 + 10.) # upper bound for lat # Plotting the map font = {'weight' : 'normal', 'size': 16} plt.rc('font', **font) fig = plt.figure(figsize=(18, 18)) ax = fig.add_subplot(111) plt.subplots_adjust(bottom=0.6) m = Basemap(llcrnrlat=llat, urcrnrlat=ulat, llcrnrlon=llon, urcrnrlon=ulon) m.drawparallels(np.arange(llat, ulat, 5.), labels=[0, 1, 0, 0]) m.drawcoastlines(color='grey') m.drawcountries() m.drawmeridians(np.arange(llon, ulon, 5.), labels=[0, 0, 0, 1]) plt.plot(polygon[:,0], polygon[:,1], 'k', linewidth=3) plt.plot(y1,x1,'k+',ms=20, mew=3) flag = 'W' # indicating that the intensity is in terms of wind-speed for it in xrange(year_st, year_en+1): data = re_da.read_obs_NH(it, flag) # reading data num_storms, max_num, num_track, lons, lats, inten, \ track_ids, time = extr.extract(data) # extracting data # Plotting the track points using the paths package # We need to check the points for j in xrange(0, num_storms): for i in xrange(0, max_num-1): # making lat and lon coordinates into a point poin = shapely.geometry.Point([lons[i,j], lats[i,j]]) if POL.contains(poin): # Checking if the polygon contains the point # In case the track needs to separate in the two sides of the map # we use a white line to connect the points if (lons[i,j]>340 and lons[i,j]<360 and lons[i+1,j]>0 and lons[i+1,j]<20): verts = [(lons[i,j], lats[i,j]), (lons[i+1,j], lats[i+1,j])] codes = [Path.MOVETO, Path.LINETO] path = Path(verts, codes) patch = patches.PathPatch(path, color='white', lw=1, alpha=0.2) ax.add_patch(patch) # In case the track needs to separate in the two sides of the map # we use a white line to connect the points elif (lons[i,j]>0 and lons[i,j]<20 and lons[i+1,j]>340 and lons[i+1,j]<360): verts = [(lons[i,j], lats[i,j]), (lons[i+1,j], lats[i+1,j])] codes = [Path.MOVETO, Path.LINETO] path = Path(verts, codes) patch = patches.PathPatch(path, color='white', lw=1, alpha=0.2) ax.add_patch(patch) # Otherwise we use a black line else: verts = [(lons[i,j], lats[i,j]), (lons[i+1,j], lats[i+1,j])] codes = [Path.MOVETO, Path.LINETO] path = Path(verts, codes) patch = patches.PathPatch(path, color='black', lw=1, alpha=0.2) ax.add_patch(patch) m.scatter(lons[:,j],lats[:,j],s=15,c=inten[:,j], cmap='viridis') # showing intensity m.plot(lons[0, j], lats[0, j], "+", ms=8, markeredgewidth=2 ,color='red') # location of genesis m.plot(lons[0, 0], lats[0, 0], "+", label='Cyclogenesis', ms=8, markeredgewidth=2 ,color='red') # location of genesis for the 1st point clb = plt.colorbar(aspect=70, orientation = 'vertical',fraction=0.05) clb.set_label('Wind speed (m$s^{-1}$)', fontsize=16) #clb.set_title('Intensity')#('Power') plt.xlabel('\n \n Longitude',fontsize=16) plt.ylabel('\n Latitude',fontsize=16) plt.title('%s' %name) legend_properties = {'weight':'bold'} plt.legend(loc='lower right',prop=legend_properties) plt.savefig('DATA\%s\PLOTS\%s_tracks.png' %(name, name), bbox_inches='tight') plt.show() return #storms_in_pol_map(29.951065, -90.071533, 'New Orleans')
m = (lon_lat[1 + i][1] - lon_lat[i][1]) / (lon_lat[i + 1][0] - lon_lat[i][0]) #print(m) #tan inverse of slop to get angle and checking the quadrant of angle if lon_lat[i + 1][0] - lon_lat[i][0] > 0: angle = degrees(atan(m)) #print(angle) else: angle = 180 + degrees(atan(m)) if angle > 360: angle = angle - 360 #print(angle) dist = geog.distance(lon_lat[i], lon_lat[i + 1]) #print(dist) rang = np.arange(0, dist, 1) #print(rang) t = i * 100 #print("----------------------------",t,"------------------------------------") line_points.append(lon_lat[i]) #print("------------------------------",len(line_points),"-------------------------------------------") for l in range(t + 1, t + 100): line_points.append(geog.propagate(line_points[int(l - 1)], angle, d)) #print(l," ----",line_points[int(l-1)]) #print(line_points[int(l-1)]) #print(m,t) for l in range(t - 1, t + 99): print(line_points[l][1]) #print(t)
e85['Points'] = list(zip(e85['Longitude'], e85['Latitude'])) e85 = e85[['Station Name', 'City', 'County', 'State', 'ZIP', 'Points']] e85.groupby('County').count().sort_values(by='City', ascending=False).head(5) e85_points = e85['Points'] geo_df = pd.DataFrame() geo_df['points'] = e85_points geometry_string = [] for i, j in tqdm(list(enumerate(e85_points))): p = Point(j) n_points = 20 d = 10 * 1000 # meters --- distance in km angles = np.linspace(0, 360, n_points) polygon = geog.propagate(p, angles, d) geometry_string.append(shapely.geometry.Polygon(polygon)) geo_df['coordinates'] = geometry_string geo_df['name'] = e85['County'] desc = [] for i in range(geo_df.shape[0]): desc.append('e85 station') geo_df['description'] = desc boundary = gpd.GeoSeries(cascaded_union(geometry_string)) boundary.plot() boundary = boundary.to_frame() plt.figure(figsize=(40, 20)) # plt.show()