예제 #1
0
def scale_bar(ax, lat, lon, length, location=(0.5, 0.05), linewidth=5):
    """
    ax is the axes to draw the scalebar on.
    location is center of the scalebar in axis coordinates ie. 0.5 is the middle of the plot
    length is the length of the scalebar in km.
    linewidth is the thickness of the scalebar.
    """
    import utm
    import cartopy.crs as ccrs
    #Projection in metres, need to change this to suit your own figure
    zone = utm.latlon_to_zone_number(lat,lon)
    if lat < 0:
        sh = True
    else:
        sh = False
    utm_c = ccrs.UTM(zone, southern_hemisphere=sh)
    #Get the extent of the plotted area in coordinates in metres
    x0, x1, y0, y1 = ax.get_extent(utm_c)
    #Turn the specified scalebar location into coordinates in metres
    sbcx, sbcy = x0 + (x1 - x0) * location[0], y0 + (y1 - y0) * location[1]
    #Generate the x coordinate for the ends of the scalebar
    for i in range(0,length):
        if i % 2 == 0:
            c = 'k'
        else:
            c = 'w'
        bar_xs = [sbcx - length * 500 + i * 1000, sbcx - length * 500 + (i+1) * 1000]
        #Plot the scalebar
        ax.plot(bar_xs, [sbcy, sbcy], transform=utm_c, color=c, linewidth=linewidth)
    #Plot the scalebar label
    sbcy = sbcy + (y1 - y0) * 0.02
    ax.text(sbcx, sbcy, str(length) + ' km', color="black", transform=utm_c, fontweight="bold",
            horizontalalignment='center', verticalalignment='bottom', fontsize=15)
예제 #2
0
    def read(self, filename, **kwargs):
        """
        :param filename: ROI_PAC binary file
        :type filename: str
        :param par_file: Corresponding parameter (:file:`*rsc`) file.
                         (optional)
        :type par_file: str
        :returns: Import dictionary
        :rtype: dict
        :raises: ImportError
        """
        par_file = kwargs.pop('par_file', self._getParameterFile(filename))

        par = self._parseParameterFile(par_file)
        nlines = int(par['FILE_LENGTH'])
        nrows = int(par['WIDTH'])
        wavelength = par['WAVELENGTH']
        heading = par['HEADING_DEG']
        lat_ref = par['LAT_REF1']
        lon_ref = par['LON_REF1']
        look_ref1 = par['LOOK_REF1']
        look_ref2 = par['LOOK_REF2']
        look_ref3 = par['LOOK_REF3']
        look_ref4 = par['LOOK_REF4']

        utm_zone_letter = utm.latitude_to_zone_letter(
                    par['LAT_REF1'])
        utm_zone = utm.latlon_to_zone_number(par['LAT_REF1'], par['LON_REF1'])

        look = num.mean(
            num.array([look_ref1, look_ref2, look_ref3, look_ref4]))

        data = num.memmap(filename, dtype='<f4')
        data = data.reshape(nlines, nrows*2)

        displ = data[:, nrows:]
        displ[displ == -0.] = num.nan
        displ = displ / (4.*num.pi) * wavelength

        z_scale = par.get('Z_SCALE', 1.)
        z_offset = par.get('Z_OFFSET', 0.)
        displ += z_offset
        displ *= z_scale

        c = self.container

        c.displacement = displ
        c.theta = 90. - look
        c.phi = -heading - 180

        c.meta.title = par.get('TITLE', 'None')
        c.meta.wavelength = par['WAVELENGTH']
        c.bin_file = filename
        c.par_file = par_file

        c.frame.llLat = par['Y_FIRST'] + par['Y_STEP'] * nrows
        c.frame.llLon = par['X_FIRST']
        c.frame.dLon = par['X_STEP']
        c.frame.dLat = par['Y_STEP']
        return self.container
예제 #3
0
def get_area_from_geometry(geom, src_crs="epsg:4326"):
    """Semi-accurately calculates the area for an input GeoJSON shape in km^2 by reprojecting it into a local UTM coordinate system.

    Args:
        geom (dict): A polygon (or multipolygon) in GeoJSON format
        src_crs (str, optional): The CRS of `geom`. Defaults to "epsg:4326".

    Raises:
        ValueError: This will be thrown if geom isn't formatted correctly, or is not a Polygon or MultiPolygon type

    Returns:
        area (float): The area of `geom` in km^2
    """

    # get one of the coordinates
    try:
        if geom["type"] == "Polygon":
            lon, lat = geom["coordinates"][0][0]
        elif geom["type"] == "MultiPolygon":
            lon, lat = geom["coordinates"][0][0][0]
        else:
            raise ValueError("Polygons and MultiPolygons only")
    except:
        raise ValueError("Input shape is not in the correct format")

    zone_number = utm.latlon_to_zone_number(lat, lon)
    hemisphere = "+north" if lat > 0 else "+south"
    dest_crs = "+proj=utm +zone=%d %s +datum=WGS84 +units=m +no_defs" % (zone_number, hemisphere)
    projected_geom = fiona.transform.transform_geom(src_crs, dest_crs, geom)
    area = shapely.geometry.shape(projected_geom).area / 1000000.0 # we calculate the area in square meters then convert to square kilometers
    return area
예제 #4
0
파일: utils.py 프로젝트: shahbazbaig/IS18
def utm_from_latlon(lats, lons):
    import utm
    import pyproj
    n = utm.latlon_to_zone_number(lats[0], lons[0])
    l = utm.latitude_to_zone_letter(lats[0])
    proj_src = pyproj.Proj('+proj=latlong')
    proj_dst = pyproj.Proj('+proj=utm +zone={}{}'.format(n, l))
    return pyproj.transform(proj_src, proj_dst, lons, lats)
    def unique(shape):
        ## Determine whether the administrative division is within a single UTM

        shape.to_crs('epsg:4326', inplace=True)

        shape['min'] = list(zip(shape.bounds['miny'], shape.bounds['minx']))
        uniq_min = shape['min'].apply(
            lambda x: utm.latlon_to_zone_number(*x)).unique()
        shape.drop(columns=['min'], inplace=True)

        shape['max'] = list(zip(shape.bounds['maxy'], shape.bounds['maxx']))
        uniq_max = shape['max'].apply(
            lambda x: utm.latlon_to_zone_number(*x)).unique()
        shape.drop(columns=['max'], inplace=True)

        uniq = np.unique(np.append(uniq_min, uniq_max))
        if uniq.shape[0] > 1:
            print("ERROR: Cross-UTM input shapefile not yet supported.")
            sys.exit(0)

        return (uniq)
예제 #6
0
def get_area_from_geometry(geom, src_crs="epsg:4326"):
    if geom["type"] == "Polygon":
        lon, lat = geom["coordinates"][0][0]
    elif geom["type"] == "MultiPolygon":
        lon, lat = geom["coordinates"][0][0][0]
    else:
        raise ValueError("Polygons and MultiPolygons only")

    zone_number = utm.latlon_to_zone_number(lat, lon)
    hemisphere = "+north" if lat > 0 else "+south"
    dest_crs = "+proj=utm +zone=%d %s +datum=WGS84 +units=m +no_defs" % (zone_number, hemisphere)
    projected_geom = fiona.transform.transform_geom(src_crs, dest_crs, geom)
    area = shapely.geometry.shape(projected_geom).area / 1000000.0 # we calculate the area in square meters then convert to square kilometers
    return area
예제 #7
0
def utm_from_latlon(lats, lons):
    """
    Fast function to convert latitudes, longitudes to UTM coordinates.
    """
    import utm
    import pyproj
    n = utm.latlon_to_zone_number(lats[0], lons[0])
    l = utm.latitude_to_zone_letter(lats[0])
    proj_src = pyproj.Proj('+proj=latlong')

    srs = '+proj=utm +zone={}{}'.format(n, l)
    if l < 'N':  # latitude bands in the southern hemisphere range from 'C' to 'M'
        srs += ' +south'
    proj_dst = pyproj.Proj(srs)

    return pyproj.transform(proj_src, proj_dst, lons, lats)
예제 #8
0
def get_utm_zone(x, y, epsg_in=4326):
    # type: (float, float, int) -> (int, str)
    """
    Get UTM zone from a given coordinate.

    :param x: x-coordinate
    :param y: y-coordinate
    :param epsg_in: EPSG code of input coordinates
    :return: Tuple of UTM zone number as integer and Hemisphere as string
    """
    if epsg_in != 4326:
        x, y = project_coords_epsg(x, y, epsg_in, 4326)
    zone_num = utm.latlon_to_zone_number(y, x)
    zone_letter = utm.latitude_to_zone_letter(y)
    zone_letter = 'N' if zone_letter > 'M' else 'S'
    return zone_num, zone_letter
예제 #9
0
    def unique(shape):
        ## Determine whether the administrative division is within a single UTM

        shape.to_crs('epsg:4326', inplace=True)

        ## TODO: make this majority count an option
        ##  and bring back cross-utm error as default behaviour
        uniq = shape.representative_point().apply(
            lambda p: utm.latlon_to_zone_number(p.y, p.x)).value_counts(
            ).idxmax()

        #if uniq.shape[0] > 1:
        #    print("ERROR: Cross-UTM input shapefile not yet supported.")
        #    sys.exit(0)

        return (uniq)
예제 #10
0
    def read(self, filename, **kwargs):
        """
        :param filename: ROI_PAC binary file
        :type filename: str
        :param par_file: Corresponding parameter (:file:`*rsc`) file.
                         (optional)
        :type par_file: str
        :returns: Import dictionary
        :rtype: dict
        :raises: ImportError
        """
        par_file = kwargs.pop('par_file', self._getParameterFile(filename))

        par, geo_ref = self._parseParameterFile(par_file)
        nlines = int(par['FILE_LENGTH'])
        nrows = int(par['WIDTH'])
        wavelength = par['WAVELENGTH']
        heading = par['HEADING_DEG']
        if geo_ref == 'latlon':
            lat_ref = par['Y_FIRST']
            lon_ref = par['X_FIRST']
        elif geo_ref == 'all':
            lat_ref = par['LAT_REF3']
            lon_ref = par['LON_REF3']

        look_ref1 = par['LOOK_REF1']
        look_ref2 = par['LOOK_REF2']
        look_ref3 = par['LOOK_REF3']
        look_ref4 = par['LOOK_REF4']

        utm_zone_letter = utm.latitude_to_zone_letter(lat_ref)
        utm_zone = utm.latlon_to_zone_number(lat_ref, lon_ref)

        look = num.mean(
            num.array([look_ref1, look_ref2, look_ref3, look_ref4]))

        data = num.memmap(filename, dtype='<f4')
        data = data.reshape(nlines, nrows*2)

        displ = data[:, nrows:]
        displ = num.flipud(displ)
        displ[displ == -0.] = num.nan
        displ = displ / (4.*num.pi) * wavelength

        z_scale = par.get('Z_SCALE', 1.)
        z_offset = par.get('Z_OFFSET', 0.)
        displ += z_offset
        displ *= z_scale

        c = self.container

        c.displacement = displ
        c.theta = num.deg2rad(90. - look)
        c.phi = num.deg2rad(-heading + 180.)

        c.meta.title = par.get('TITLE', 'None')
        c.meta.wavelength = par['WAVELENGTH']
        c.bin_file = filename
        c.par_file = par_file

        if geo_ref == 'all':
            if par['X_UNIT'] == 'meters':
                c.frame.spacing = 'meter'
                c.frame.dE = par['X_STEP']
                c.frame.dN = -par['Y_STEP']
                geo_ref = 'utm'

            elif par['X_UNIT'] == 'degree':
                c.frame.spacing = 'degree'
                geo_ref = 'latlon'

        elif geo_ref == 'latlon':
            self._log.info('Georeferencing is in Lat-Lon [degrees].')
            c.frame.spacing = 'degree'
            c.frame.llLat = par['Y_FIRST'] + par['Y_STEP'] * nrows
            c.frame.llLon = par['X_FIRST']

            # c_utm_0 = utm.from_latlon(lat_ref, lon_ref)
            # c_utm_1 = utm.from_latlon(lat_ref + par['Y_STEP'],
            #                           lon_ref + par['X_STEP'])

            # c.frame.dE = c_utm_1[0] - c_utm_0[0]
            # c.frame.dN = abs(c_utm_1[1] - c_utm_0[1])
            c.frame.dE = par['X_STEP']
            c.frame.dN = -par['Y_STEP']

        elif geo_ref == 'utm':
            self._log.info('Georeferencing is in UTM (zone %d%s)',
                           utm_zone, utm_zone_letter)
            y_ll = par['Y_FIRST'] + par['Y_STEP'] * nrows
            c.frame.llLat, c.frame.llLon = utm.to_latlon(
                par['X_FIRST'], y_ll, utm_zone,
                zone_letter=utm_zone_letter)

        return self.container
예제 #11
0
    def read(self, filename, **kwargs):
        """
        :param filename: ROI_PAC binary file
        :type filename: str
        :param par_file: Corresponding parameter (:file:`*rsc`) file.
                         (optional)
        :type par_file: str
        :returns: Import dictionary
        :rtype: dict
        :raises: ImportError
        """
        par_file = kwargs.pop("par_file", self._getParameterFile(filename))

        par, geo_ref = self._parseParameterFile(par_file)
        nlines = int(par["FILE_LENGTH"])
        ncols = int(par["WIDTH"])
        wavelength = par["WAVELENGTH"]
        heading = par["HEADING_DEG"]
        if geo_ref == "latlon":
            lat_ref = par["Y_FIRST"]
            lon_ref = par["X_FIRST"]
        elif geo_ref == "all":
            lat_ref = par["LAT_REF3"]
            lon_ref = par["LON_REF3"]

        look_ref1 = par["LOOK_REF1"]
        look_ref2 = par["LOOK_REF2"]
        look_ref3 = par["LOOK_REF3"]
        look_ref4 = par["LOOK_REF4"]

        utm_zone_letter = utm.latitude_to_zone_letter(lat_ref)
        utm_zone = utm.latlon_to_zone_number(lat_ref, lon_ref)

        look = num.mean(num.array([look_ref1, look_ref2, look_ref3,
                                   look_ref4]))

        data = num.memmap(filename, dtype="<f4")
        data = data.reshape(nlines, ncols * 2)

        displ = data[:, ncols:]
        displ = num.flipud(displ)
        displ[displ == -0.0] = num.nan
        displ = displ / (4.0 * num.pi) * wavelength

        z_scale = par.get("Z_SCALE", 1.0)
        z_offset = par.get("Z_OFFSET", 0.0)
        displ += z_offset
        displ *= z_scale

        container = self.container

        container.displacement = displ
        container.theta = num.deg2rad(90.0 - look)
        container.phi = num.deg2rad(-heading + 180.0)

        container.meta.title = par.get("TITLE", "None")
        container.meta.wavelength = par["WAVELENGTH"]
        container.bin_file = filename
        container.par_file = par_file

        if geo_ref == "all":
            if par["X_UNIT"] == "meters":
                container.frame.spacing = "meter"
                container.frame.dE = par["X_STEP"]
                container.frame.dN = -par["Y_STEP"]
                geo_ref = "utm"

            elif par["X_UNIT"] == "degree":
                container.frame.spacing = "degree"
                geo_ref = "latlon"

        elif geo_ref == "latlon":
            self._log.info("Georeferencing is in Lat-Lon [degrees].")
            container.frame.spacing = "degree"
            container.frame.llLat = par["Y_FIRST"] + par["Y_STEP"] * nlines
            container.frame.llLon = par["X_FIRST"]

            # c_utm_0 = utm.from_latlon(lat_ref, lon_ref)
            # c_utm_1 = utm.from_latlon(lat_ref + par['Y_STEP'],
            #                           lon_ref + par['X_STEP'])

            # c.frame.dE = c_utm_1[0] - c_utm_0[0]
            # c.frame.dN = abs(c_utm_1[1] - c_utm_0[1])
            container.frame.dE = par["X_STEP"]
            container.frame.dN = -par["Y_STEP"]

        elif geo_ref == "utm":
            self._log.info("Georeferencing is in UTM (zone %d%s)", utm_zone,
                           utm_zone_letter)
            y_ll = par["Y_FIRST"] + par["Y_STEP"] * nlines
            container.frame.llLat, container.frame.llLon = utm.to_latlon(
                par["X_FIRST"], y_ll, utm_zone, zone_letter=utm_zone_letter)

        return self.container
예제 #12
0
# projection example
# The answer might be helpful for others so I have posted my solution. I found pyproj works better then utm. In pyproj we can specify utm zone.
# import pyproj
from pyproj import Proj
from pprint import pprint
from utm import latlon_to_zone_number

longs = [16.01783828, 17.0086323, 16.4784]
lats =  [48.09774797, 48.55559181, 48.231]
zone_number = latlon_to_zone_number(lats[0], longs[1])
pprint(f'zone number: {zone_number}')

pprint(f'longitudes: {longs}, latitudes: {lats}')
projection_31286_adapted = "+proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=+500000 +y_0=0 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m +no_defs"
epsg = 31286
myProj = Proj(projection_31286_adapted)
eastings, northings = myProj(longs, lats) 
pprint(f'eastings: {eastings}, northings: {northings}')

eastings_crs = [575782.1956641411, 648215.3421904881]
northings_crs = [5327665.617543304, 5380002.786198429]
pprint(f'crs transform')
pprint(f'eastings crs: {eastings_crs}, northings crs {northings_crs}')


'''
0  POINT (16.01783828 48.09774797)
1   POINT (17.0086323 48.55559181)
2018-12-14 12:11:21,086 - INFO -                                       geometry
0  POINT (575782.1956641411 5327665.617543304)
1  POINT (648215.3421904881 5380002.786198429)
예제 #13
0
파일: utils.py 프로젝트: shahbazbaig/IS18
def zonestring_from_lonlat(lon, lat):
    import utm
    n = utm.latlon_to_zone_number(lat, lon)
    l = utm.latitude_to_zone_letter(lat)
    s = "%d%s" % (n, l)
    return s
예제 #14
0
def aoi_info_from_geotiff_gt(ref_filename,
                             gt_filename,
                             padding=0.0,
                             height_guard=[-5, +5]):
    ''' aoi_from_gt
    Returns an aoi from an image and a gt

    padding: relative to the size the gt region (e.g. 0.1 adds a 10% of the extension of
    the region on the four boundaries)
    '''

    # get the dimensions of the first image
    width, height, pixel_dim = s2p.common.image_size_gdal(ref_filename)

    # get the rpc of the first image
    ref_image_rpc = rpcm.rpc_from_geotiff(ref_filename)
    # get the localization of the center of the image
    lon_center, lat_center = ref_image_rpc.localization(
        width // 2, height // 2, 0)

    zone_number = utm.latlon_to_zone_number(lat_center, lon_center)
    zone_letter = utm.latitude_to_zone_letter(lat_center)

    # Build the AOI of the GT ------------------------------

    gt_metadata = readGTIFFmeta(gt_filename)
    bounding_box = gt_metadata[1]
    gt_min_easting = bounding_box.left
    gt_max_easting = bounding_box.right
    gt_min_northing = bounding_box.bottom
    gt_max_northing = bounding_box.top

    # padding
    gt_easting_extension = gt_max_easting - gt_min_easting
    gt_northing_extension = gt_max_northing - gt_min_northing
    gt_min_easting -= padding * gt_easting_extension
    gt_max_easting += padding * gt_easting_extension
    gt_min_northing -= padding * gt_northing_extension
    gt_max_northing += padding * gt_northing_extension
    # update the extension
    gt_easting_extension = gt_max_easting - gt_min_easting
    gt_northing_extension = gt_max_northing - gt_min_northing

    # convert easting, northing to lon,lat
    gt_min_lat, gt_min_lon = utm.to_latlon(gt_min_easting, gt_min_northing,
                                           zone_number, zone_letter)
    gt_max_lat, gt_max_lon = utm.to_latlon(gt_max_easting, gt_max_northing,
                                           zone_number, zone_letter)

    zone_hemisphere = 'N' if gt_min_lat > 0 else 'S'

    aoi = {
        'coordinates': [[[gt_min_lon, gt_min_lat], [gt_min_lon, gt_max_lat],
                         [gt_max_lon, gt_max_lat], [gt_max_lon, gt_min_lat],
                         [gt_min_lon, gt_min_lat]]],
        'type':
        'Polygon'
    }

    utm_bbx = [
        gt_min_easting, gt_max_easting, gt_min_northing, gt_max_northing
    ]
    lonlat_bbx = [gt_min_lon, gt_max_lon, gt_min_lat, gt_max_lat]

    # get min and max height from the gt image
    gt = s2p.common.gdal_read_as_array_with_nans(gt_filename)
    min_height, max_height = robust_image_min_max(gt)
    # add height guard
    min_height += height_guard[0]
    max_height += height_guard[1]

    return aoi, min_height, max_height, zone_hemisphere, zone_letter, zone_number, utm_bbx, lonlat_bbx
예제 #15
0
 def convert_to_latlon(self, zone: LatLon):
     zone_number = latlon_to_zone_number(zone.lat, zone.lon)
     zone_letter = latitude_to_zone_letter(zone.lat)
     lat, lon = to_latlon(self.east, self.north, zone_number, zone_letter)
     return LatLon(lat, lon)
예제 #16
0
def get_grid_latitudes_longitudes_from_aoi(aoi, resolution=1, **kwargs):
    r""" get_grid_latitudes_longitudes_from_aoi
    
    Returns the arrays of latitudes and longitudes for a certain grid resolution on the aoi .
    
    Parameters
    ----------
    aoi :   dict with 'coordinates' key
            Area of interest (a rectangle is expected)
    resolution : double
            Resolution of the grid. Defaults to 1 (meter)
    **kwargs
        Arbitrary optional keyword argument.
        grid_shape : tuple or list or array of two integers defining the grid shape (rows (latitudes), cols (longitudes))
                     This parameter overrides resolution
    
    Returns
    -------
    latitudes:  1D numpy array
            Array of latitudes of the grid
    longitudes: 1D numpy array
            Array of longitudes of the grid
    """

    min_easting, max_easting, min_northing, max_northing = utils.utm_bounding_box_from_lonlat_aoi(
        aoi)

    if 'grid_shape' in kwargs.keys():
        m, n = kwargs.get('grid_shape')

        latitudes = np.arange(
            start=np.min(np.array(aoi['coordinates'])[0, :, 1]),
            stop=np.max(np.array(aoi['coordinates'])[0, :, 1]),
            step=(np.max(np.array(aoi['coordinates'])[0, :, 1]) -
                  np.min(np.array(aoi['coordinates'])[0, :, 1])) / m)

        longitudes = np.arange(
            start=np.min(np.array(aoi['coordinates'])[0, :, 0]),
            stop=np.max(np.array(aoi['coordinates'])[0, :, 0]),
            step=(np.max(np.array(aoi['coordinates'])[0, :, 0]) -
                  np.min(np.array(aoi['coordinates'])[0, :, 0])) / n)

    else:

        Northings = np.arange(min_northing, max_northing, resolution)
        Eastings = np.arange(min_easting, max_easting, resolution)

        zone_number = utm.latlon_to_zone_number(aoi['coordinates'][0][0][1],
                                                aoi['coordinates'][0][0][0])
        zone_letter = utm.latitude_to_zone_letter(aoi['coordinates'][0][0][1])
        latitudes = [
            utm.to_latlon(Eastings[0], Northings[i], zone_number,
                          zone_letter)[0] for i in range(len(Northings))
        ]
        longitudes = [
            utm.to_latlon(Eastings[i], Northings[0], zone_number,
                          zone_letter)[1] for i in range(len(Eastings))
        ]

        latitudes = np.array(latitudes)
        longitudes = np.array(longitudes)

    return latitudes, longitudes