コード例 #1
0
 def ellipsoid(self, acronym):
     '''Return the ellipsoid associated with the acronym'''
     if acronym == 'WGS84':
         return (Geodesic.WGS84)
     elif acronym in self.acronymList:
         param = self.acronymList[acronym].parameters
         return(Geodesic(param.semiMajor, 1.0 / param.inverseFlattening))
     elif acronym in historical_ellipsoids:
         return(Geodesic(historical_ellipsoids[acronym][1], 1.0 / historical_ellipsoids[acronym][2]))
     else:
         return(None)
コード例 #2
0
 def test_GeodSolve33(self):
     # Check max(-0.0,+0.0) issues 2015-08-22 (triggered by bugs in
     # Octave -- sind(-0.0) = +0.0 -- and in some version of Visual
     # Studio -- fmod(-0.0, 360.0) = +0.0.
     inv = Geodesic.WGS84.Inverse(0, 0, 0, 179)
     self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 19926189, delta=0.5)
     inv = Geodesic.WGS84.Inverse(0, 0, 0, 179.5)
     self.assertAlmostEqual(inv["azi1"], 55.96650, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 124.03350, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 19980862, delta=0.5)
     inv = Geodesic.WGS84.Inverse(0, 0, 0, 180)
     self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5)
     self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 20003931, delta=0.5)
     inv = Geodesic.WGS84.Inverse(0, 0, 1, 180)
     self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5)
     self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 19893357, delta=0.5)
     geod = Geodesic(6.4e6, 0)
     inv = geod.Inverse(0, 0, 0, 179)
     self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 19994492, delta=0.5)
     inv = geod.Inverse(0, 0, 0, 180)
     self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5)
     self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5)
     inv = geod.Inverse(0, 0, 1, 180)
     self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5)
     self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 19994492, delta=0.5)
     geod = Geodesic(6.4e6, -1 / 300.0)
     inv = geod.Inverse(0, 0, 0, 179)
     self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 19994492, delta=0.5)
     inv = geod.Inverse(0, 0, 0, 180)
     self.assertAlmostEqual(inv["azi1"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 90.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5)
     inv = geod.Inverse(0, 0, 0.5, 180)
     self.assertAlmostEqual(inv["azi1"], 33.02493, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 146.97364, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 20082617, delta=0.5)
     inv = geod.Inverse(0, 0, 1, 180)
     self.assertAlmostEqual(inv["azi1"], 0.00000, delta=0.5e-5)
     self.assertAlmostEqual(abs(inv["azi2"]), 180.00000, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 20027270, delta=0.5)
コード例 #3
0
def _Geodesic(points, closed, datum, line, wrap):
    # Compute the area or perimeter of a polygon/-line
    # using the GeographicLib package, iff installed
    try:
        from geographiclib.geodesic import Geodesic
    except ImportError:
        raise ImportError('no %s' % ('geographiclib', ))

    if not wrap:  # capability LONG_UNROLL always set
        raise ValueError('%s invalid: %s' % ('wrap', wrap))

    _, points = polygon(points,
                        closed=closed)  # base=LatLonEllipsoidalBase(0, 0)

    E = datum.ellipsoid
    g = Geodesic(E.a, E.f).Polygon(line)

    # note, lon deltas are unrolled, by default
    for p in points:
        g.AddPoint(p.lat, p.lon)
    if line and closed:
        p = points[0]
        g.AddPoint(p.lat, p.lon)

    # g.Compute returns (number_of_points, perimeter, signed area)
    return g.Compute(False, True)[1 if line else 2]
コード例 #4
0
def get_endpoint(lat1, lon1, bearing, d):


    geod = Geodesic(Constants.WGS84_a, Constants.WGS84_f)
    d = geod.Direct(lat1, lon1, bearing, d)#* 1852.0)

    return d['lat2'], d['lon2']
コード例 #5
0
ファイル: localization.py プロジェクト: stevenlujpl/pdsc
class CtxLocalizer(GeodesicLocalizer):
    """
    A localizer for the CTX instrument (subclass of
    :py:class:`GeodesicLocalizer`)
    """

    DEFAULT_RESOLUTION_M = 1e-3
    """
    Sets the default resolution for CTX localization
    """

    BODY = Geodesic(MARS_RADIUS_M, 0.0) # Works better assuming sphere
    """
    Uses a Geodesic model for CTX that assumes Mars is spherical, which seems to
    work better in practice.
    """

    def __init__(self, metadata):
        """
        :param metadata:
            "ctx" :py:class:`~pdsc.metadata.PdsMetadata` object
        """
        flipped_na = (180 - metadata.north_azimuth
            if metadata.usage_note == 'F' else metadata.north_azimuth)
        super(CtxLocalizer, self).__init__(
            metadata.lines / 2.0, metadata.samples / 2.0,
            metadata.center_latitude, metadata.center_longitude,
            metadata.lines, metadata.samples,
            metadata.image_height / metadata.lines,
            metadata.image_width / metadata.samples,
            flipped_na, -1
        )
コード例 #6
0
def get_gc_positions(start, end):
    """
    Get positions along a Great Circle to enable plotting.
    I couldn't do this with Basemap as we have to instantiate
    first and we don't know the map boundaries until we have the GC
    positions.

    :param start: The start position
    :type start: tuple
    :param end: The end position
    :type end: tuple
    :return: list of positions
    :rtype: list of dict
    """
    positions = []
    spacing = 100000  # Positions 100km apart
    geoid = Geodesic(Constants.WGS84_a, Constants.WGS84_f)
    gc = geoid.InverseLine(
            start[0], start[1],
            end[0], end[1]
    )

    n = math.ceil(gc.s13 / spacing)

    for i in range(n + 1):
        s = min(spacing * i, gc.s13)
        result = gc.Position(s, Geodesic.STANDARD | Geodesic.LONG_UNROLL)
        position = {
            'Lat': result['lat2'],
            'Lon': result['lon2']
        }
        positions.append(position)

    return positions
コード例 #7
0
ファイル: localization.py プロジェクト: stevenlujpl/pdsc
class MocLocalizer(GeodesicLocalizer):
    """
    A localizer for the MOC observations (subclass of
    :py:class:`GeodesicLocalizer`)
    """

    DEFAULT_RESOLUTION_M = 1e-3
    """
    Sets the default resolution for MOC localization
    """

    BODY = Geodesic(MARS_RADIUS_M, 0.0)
    """
    Uses a Geodesic model for MOC that assumes Mars is spherical, which seems to
    work better in practice.
    """

    def __init__(self, metadata):
        """
        :param metadata:
            "moc" :py:class:`~pdsc.metadata.PdsMetadata` object
        """
        super(MocLocalizer, self).__init__(
            metadata.lines / 2.0, metadata.samples / 2.0,
            metadata.center_latitude, metadata.center_longitude,
            metadata.lines, metadata.samples,
            metadata.image_height / metadata.lines,
            metadata.image_width / metadata.samples,
            metadata.north_azimuth, 1
        )
コード例 #8
0
def getEndpoint(lat1, lon1, d1, d2):
    bearing = random.uniform(0, 360)
    dist = random.uniform(d1, d2)
    radius = (d2-d1)/2
    geod = Geodesic(Constants.WGS84_a, Constants.WGS84_f)
    d = geod.Direct(lat1, lon1, bearing, dist)
    return d['lon2'], d['lat2'], radius
コード例 #9
0
    def __init__(self):
        """Initiate all instances of the classes that are needed for the simulation, and start PyGame.

        Raises:
            Exception: If you fail to choose a valid simulation setting, an Exception is raised.
        """
        while True:
            try:
                string = str(
                    input('Do you want to take in live GNSS-signals? (y/n)\t'))
                if string in ('y', 'yes'):
                    self.test_mode_on = False
                    try:
                        self.gps = serial.Serial('/dev/ttyACM0', baudrate=9600)
                    except Exception:
                        print(
                            "The port cannot be opened. Check that your unit is connected to the port you're opening."
                        )
                        exit()
                elif string in ('n', 'no'):
                    self.test_mode_on = True
                else:
                    raise Exception
            except Exception:
                print('Please type "y" or "n".')
            else:
                break
        self.clock = pg.time.Clock()
        self.the_arrow = Arrow()
        self.map = Map(60.75, 11.99)
        self.the_text = Text()
        self.earth = Geodesic(cf.R_E, 0)
        self.out_q = mp.Manager().Value('i', [0.0, 0.0])
        self.NS = self.map.center_y
        self.EW = self.map.center_x
        self.the_background = pg.image.load('background.jpg')
        self.process = False
        self.background = False
        self.dot_x, self.dot_y = self.the_arrow.two_d_pos.x, self.the_arrow.two_d_pos.y
        self.pastNS, self.pastEW = self.NS, self.EW
        # Create a new log file for this session.
        with open("log.txt", "w") as log:
            log.write("")
        try:
            what_os = platform.system()
            if what_os == 'Linux':
                self.g_earth = subprocess.Popen('google-earth-pro')
            elif what_os == 'Darwin':
                subprocess.call([
                    "/usr/bin/open", "-n", "-a",
                    "/Applications/Google Earth Pro.app"
                ])
        except Exception:
            pass
        # Wait for Google Earth Pro to open so that the PyGame window opens as the top layer.
        time.sleep(5)
        pg.init()
        pg.display.set_caption("Real time spoofer")
        self.screen = pg.display.set_mode((cf.SCREEN_WIDTH, cf.SCREEN_HEIGHT))
コード例 #10
0
 def test_GeodSolve12(self):
     # Check fix for inverse geodesics on extreme prolate/oblate
     # ellipsoids Reported 2012-08-29 Stefan Guenther
     # <*****@*****.**>; fixed 2012-10-07
     geod = Geodesic(89.8, -1.83)
     inv = geod.Inverse(0, 0, -10, 160)
     self.assertAlmostEqual(inv["azi1"], 120.27, delta=1e-2)
     self.assertAlmostEqual(inv["azi2"], 105.15, delta=1e-2)
     self.assertAlmostEqual(inv["s12"], 266.7, delta=1e-1)
コード例 #11
0
ファイル: base.py プロジェクト: huazhz/seismology
def gps2dist_azimuth(lat1, lon1, lat2, lon2, a=WGS84_A, f=WGS84_F):
    """
    Computes the distance between two geographic points on the WGS84
    ellipsoid and the forward and backward azimuths between these points.

    :param lat1: Latitude of point A in degrees (positive for northern,
        negative for southern hemisphere)
    :param lon1: Longitude of point A in degrees (positive for eastern,
        negative for western hemisphere)
    :param lat2: Latitude of point B in degrees (positive for northern,
        negative for southern hemisphere)
    :param lon2: Longitude of point B in degrees (positive for eastern,
        negative for western hemisphere)
    :param a: Radius of Earth in m. Uses the value for WGS84 by default.
    :param f: Flattening of Earth. Uses the value for WGS84 by default.
    :return: (Great circle distance in m, azimuth A->B in degrees,
        azimuth B->A in degrees)

    .. note::
        This function will check if you have installed the Python module
        `geographiclib <http://geographiclib.sf.net>`_ - a very fast module
        for converting between geographic, UTM, UPS, MGRS, and geocentric
        coordinates, for geoid calculations, and for solving geodesic problems.
        Otherwise the locally implemented Vincenty's Inverse formulae
        (:func:`obspy.core.util.geodetics.calc_vincenty_inverse`) is used which
        has known limitations for two nearly antipodal points and is ca. 4x
        slower.
    """
    if HAS_GEOGRAPHICLIB:
        if lat1 > 90 or lat1 < -90:
            msg = "Latitude of Point 1 out of bounds! (-90 <= lat1 <=90)"
            raise ValueError(msg)
        if lat2 > 90 or lat2 < -90:
            msg = "Latitude of Point 2 out of bounds! (-90 <= lat2 <=90)"
            raise ValueError(msg)
        result = Geodesic(a=a, f=f).Inverse(lat1, lon1, lat2, lon2)
        azim = result['azi1']
        if azim < 0:
            azim += 360
        bazim = result['azi2'] + 180
        return (result['s12'], azim, bazim)
    else:
        try:
            values = calc_vincenty_inverse(lat1, lon1, lat2, lon2, a, f)
            if np.alltrue(np.isnan(values)):
                raise StopIteration
            return values
        except StopIteration:
            msg = ("Catching unstable calculation on antipodes. "
                   "The currently used Vincenty's Inverse formulae "
                   "has known limitations for two nearly antipodal points. "
                   "Install the Python module 'geographiclib' to solve this "
                   "issue.")
            warnings.warn(msg)
            return (20004314.5, 0.0, 0.0)
        except ValueError as e:
            raise e
コード例 #12
0
def calc_dist_azi(source_latitude_in_deg, source_longitude_in_deg,
                  receiver_latitude_in_deg, receiver_longitude_in_deg,
                  radius_of_planet_in_km, flattening_of_planet):
    """
    Given the source and receiver location, calculate the azimuth from the
    source to the receiver at the source, the backazimuth from the receiver
    to the source at the receiver and distance between the source and receiver.

    :param source_latitude_in_deg: Source location latitude in degrees
    :type source_latitude_in_deg: float
    :param source_longitude_in_deg: Source location longitude in degrees
    :type source_longitude_in_deg: float
    :param receiver_latitude_in_deg: Receiver location latitude in degrees
    :type receiver_latitude_in_deg: float
    :param receiver_longitude_in_deg: Receiver location longitude in degrees
    :type receiver_longitude_in_deg: float
    :param radius_of_planet_in_km: Radius of the planet in km
    :type radius_of_planet_in_km: float
    :param flattening_of_planet: Flattening of planet (0 for a sphere)
    :type receiver_longitude_in_deg: float

    :returns: distance_in_deg (in degrees), source_receiver_azimuth (in
              degrees) and receiver_to_source_backazimuth (in degrees).
    :rtype: tuple of three floats
    """
    if geodetics.HAS_GEOGRAPHICLIB:
        ellipsoid = Geodesic(a=radius_of_planet_in_km * 1000.0,
                             f=flattening_of_planet)
        g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg,
                              receiver_latitude_in_deg,
                              receiver_longitude_in_deg)
        distance_in_deg = g['a12']
        source_receiver_azimuth = g['azi1'] % 360
        receiver_to_source_backazimuth = (g['azi2'] + 180) % 360

    else:
        # geographiclib is not installed - use obspy/geodetics
        values = gps2dist_azimuth(source_latitude_in_deg,
                                  source_longitude_in_deg,
                                  receiver_latitude_in_deg,
                                  receiver_longitude_in_deg,
                                  a=radius_of_planet_in_km * 1000.0,
                                  f=flattening_of_planet)
        distance_in_km = values[0] / 1000.0
        source_receiver_azimuth = values[1] % 360
        receiver_to_source_backazimuth = values[2] % 360
        # NB - km2deg assumes spherical planet... generate a warning
        if flattening_of_planet != 0.0:
            msg = "Assuming spherical planet when calculating epicentral " + \
                  "distance. Install the Python module 'geographiclib' " + \
                  "to solve this."
            warnings.warn(msg)
        distance_in_deg = kilometer2degrees(distance_in_km,
                                            radius=radius_of_planet_in_km)
    return (distance_in_deg, source_receiver_azimuth,
            receiver_to_source_backazimuth)
コード例 #13
0
 def test_GeodSolve2(self):
     # Check fix for antipodal prolate bug found 2010-09-04
     geod = Geodesic(6.4e6, -1 / 150.0)
     inv = geod.Inverse(0.07476, 0, -0.07476, 180)
     self.assertAlmostEqual(inv["azi1"], 90.00078, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 90.00078, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5)
     inv = geod.Inverse(0.1, 0, -0.1, 180)
     self.assertAlmostEqual(inv["azi1"], 90.00105, delta=0.5e-5)
     self.assertAlmostEqual(inv["azi2"], 90.00105, delta=0.5e-5)
     self.assertAlmostEqual(inv["s12"], 20106193, delta=0.5)
コード例 #14
0
    def measure(self, a, b):
        a, b = Point(a), Point(b)
        lat1, lon1 = a.latitude, a.longitude
        lat2, lon2 = b.latitude, b.longitude

        if not (isinstance(self.geod, Geodesic) and self.geod.a
                == self.ELLIPSOID[0] and self.geod.f == self.ELLIPSOID[2]):
            self.geod = Geodesic(self.ELLIPSOID[0], self.ELLIPSOID[2])

        s12 = self.geod.Inverse(lat1, lon1, lat2, lon2,
                                Geodesic.DISTANCE)['s12']

        return s12
コード例 #15
0
ファイル: taup_geo.py プロジェクト: maratumba/obspy-gcfio
def calc_dist(source_latitude_in_deg, source_longitude_in_deg,
              receiver_latitude_in_deg, receiver_longitude_in_deg,
              radius_of_earth_in_km, flattening_of_earth):
    """
    Given the source and receiver location, calculate the azimuth and distance.

    :param source_latitude_in_deg: Source location latitude in degrees
    :type source_latitude_in_deg: float
    :param source_longitude_in_deg: Source location longitude in degrees
    :type source_longitude_in_deg: float
    :param receiver_latitude_in_deg: Receiver location latitude in degrees
    :type receiver_latitude_in_deg: float
    :param receiver_longitude_in_deg: Receiver location longitude in degrees
    :type receiver_longitude_in_deg: float
    :param radius_of_earth_in_km: Radius of the Earth in km
    :type radius_of_earth_in_km: float
    :param flattening_of_earth: Flattening of Earth (0 for a sphere)
    :type receiver_longitude_in_deg: float

    :return: distance_in_deg
    :rtype: float
    """
    if geodetics.HAS_GEOGRAPHICLIB:
        ellipsoid = Geodesic(a=radius_of_earth_in_km*1000.0,
                             f=flattening_of_earth)
        g = ellipsoid.Inverse(source_latitude_in_deg,
                              source_longitude_in_deg,
                              receiver_latitude_in_deg,
                              receiver_longitude_in_deg)
        distance_in_deg = g['a12']

    else:
        # geographiclib is not installed - use obspy/geodetics
        values = gps2dist_azimuth(source_latitude_in_deg,
                                  source_longitude_in_deg,
                                  receiver_latitude_in_deg,
                                  receiver_longitude_in_deg,
                                  a=radius_of_earth_in_km*1000.0,
                                  f=flattening_of_earth)
        distance_in_km = values[0]/1000.0
        # NB - km2deg assumes spherical Earth... generate a warning
        if flattening_of_earth != 0.0:
            msg = "Assuming spherical Earth when calculating epicentral " + \
                  "distance. Install the Python module 'geographiclib' " + \
                  "to solve this."
            warnings.warn(msg)
        distance_in_deg = kilometer2degrees(distance_in_km,
                                            radius=radius_of_earth_in_km)
    return distance_in_deg
コード例 #16
0
ファイル: rdp.py プロジェクト: Rice-Tectonics-Group/PySkew
def find_corners(lat_lon_file,
                 tolerance=1,
                 min_angle=np.pi * 0.22,
                 geoid=Geodesic(6371., 0.),
                 lsz=None):
    """
    Credit to unutbu from Stack Overflow
    (https://stackoverflow.com/questions/14631776/calculate-turning-points-pivot-points-in-trajectory-path)
    Modifed by PySkew author Kevin Gaastra to run on a sphere

    Runs the Ramer-Douglas-Peucker algorithm to simplify the lat, lon path stored in the specified lat_lon_file.
    It prints out the number of points in the origional path and the number of points in the simplified path.
    Then calculates the points in the simplified path that constitute a turn greater than min_angle.
    
    Parameters
    ----------
    lat_lon_file - file containing lattitude and longitude in that order in columns seperated by whitespace
    tolerance - the tolerance of the RDP algorithm more tolerance=less points kept (default=1)
    min_angle - angle in radians that should constitute a "significant" change in heading
    
    Returns
    -------
    Tuple - (numpy array number_of_points_in_origionalx2 containing the origional data, 
    number_of_points_in_simplifiedx2 containing the simplified data, and an array containing the locations in
    the simplified data where turns exceeding min_angle are found)
    """
    path = os.path.expanduser(lat_lon_file)
    points = np.genfromtxt(path)
    print("original number of points = %d" % len(points))

    # Use the Ramer-Douglas-Peucker algorithm to simplify the path
    # http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
    # Python implementation: https://github.com/sebleier/RDP/
    simplified = np.array(
        rdp.rdp(points.tolist(), tolerance, dist=create_geo_gc_dist(geoid)))
    #    simplified = np.array(kmg9_rdp(points.tolist(), tolerance, create_geo_gc_dist(geoid),lsz=lsz))

    print("simplified number of points = %d" % len(simplified))

    # compute the direction vectors on the simplified curve
    #    directions = np.diff(simplified, axis=0)
    theta = geo_angle(simplified)
    # Select the index of the points with the greatest theta
    # Large theta is associated with greatest change in direction.
    idx = np.where(theta > np.rad2deg(min_angle))[0] + 1
    print("number of significant turns = %d" % len(idx))

    return points, simplified, idx
コード例 #17
0
ファイル: distance.py プロジェクト: JF451/VaccineSite
    def destination(self, point, bearing, distance=None):
        point = Point(point)
        lat1 = point.latitude
        lon1 = point.longitude
        azi1 = bearing

        if distance is None:
            distance = self
        if isinstance(distance, Distance):
            distance = distance.kilometers

        if not (isinstance(self.geod, Geodesic) and self.geod.a
                == self.ELLIPSOID[0] and self.geod.f == self.ELLIPSOID[2]):
            self.geod = Geodesic(self.ELLIPSOID[0], self.ELLIPSOID[2])

        r = self.geod.Direct(lat1, lon1, azi1, distance,
                             Geodesic.LATITUDE | Geodesic.LONGITUDE)

        return Point(r['lat2'], r['lon2'])
コード例 #18
0
ファイル: rdp.py プロジェクト: Rice-Tectonics-Group/PySkew
def geo_angle(points, geoid=Geodesic(6371., 0.)):
    """
    Returns the angles between two great circles for a set of points

    Parameters
    ----------
    points : 2D-Ndarray
        lat-lon array of points on a sphere between which to calculate angles

    Returns
    ----------
    angles : 1D-Ndarray
        angles between the great circles defined by points of shape (N-1,), with each value between 0 and 180 degrees.
    """
    return np.abs(
        np.diff(
            list(
                map(lambda a, b, c, d: geoid.Inverse(a, b, c, d)["azi1"],
                    points[:-1, 0], points[:-1,
                                           1], points[1:, 0], points[1:, 1]))))
コード例 #19
0
	def calculate_distances(self):
		#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		# Calculates the distance between all neuron positions *along the surface* (using geodesic distances) ~
		#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		# The geographiclib.geodesic module is needed to calculate geodesic distance along the surface of a spheroid.
		# - Library is based on Karney 2013 (seemingly written by Karney himself)
		# - See https://geographiclib.sourceforge.io/1.48/python/
		try:
			from geographiclib.geodesic import Geodesic
		except:
			exitOnNetworkGeometryError("The geographiclib.geodesic module is needed to calculate geodesic distance along the surface of a spheroid, but this module could not be imported.")
		# The Geodesic object constructor has two parameters:
		#	- a: the equatorial (xy) radius of the ellipsoid
		#	- f: the flattening of the ellipsoid. b = a(1-f) --> f = 1 - b/a  (where b is the polar (z) axis)
		a 			= self.r_xy
		b 			= self.r_z
		f 			= 1.0 - b/a
		geodesic 	= Geodesic(a, f)

		# Convert parametric coordinates (theta(lon), phi(lat)) from radian to degree angles
		degreecoords	= numpy.degrees(self.parametricCoords)
		# print self.coordinates
		# print "degrees"
		# print degreecoords

		for i in range(self.N):
			for j in range(self.N):
				# Geodesic.Inverse(...) calculates the geodesic distance between two points along a spheroid surface.
				#	arguments: 	(lat1, lon1, lat2, lon2, outmask=1025)
				#				- expects lat1, lon1, lat2, lon2 to be latitude(theta)/longitude(phi) angles in degrees
				#				- outmask=1025 tells it to return the distance measure
				#	returns:	a Geodesic dictionary including key-value pair 's12', which is the calculated distance between the points.
				lat1	= degreecoords[i][1]
				lon1	= degreecoords[i][0]
				lat2	= degreecoords[j][1]
				lon2	= degreecoords[j][0]
				# print geodesic.Inverse(lat1, lon1, lat2, lon2, outmask=1025)
				# print "lat" + str(lat1) + " lon" + str(lon1) + "  ::  lat" + str(lat2) + " lon" + str(lon2)
				dist 	= geodesic.Inverse(lat1, lon1, lat2, lon2, outmask=1025)['s12']
				self.distances[i,j]	= dist
コード例 #20
0
def globe_distance(
    lat1: float,
    lon1: float,
    lat2: float,
    lon2: float,
    round_to: int = 5,
) -> float:
    """
    Compute the great circle distance in km between two points on Earth.
    
    """

    _check_latitude(lat1, 'lat1')
    _check_latitude(lat2, 'lat2')
    result = Geodesic(a=WGS84_A, f=WGS84_F).Inverse(lat1, lon1, lat2, lon2)

    # Used to cope with minor floating point differences between operating
    # systems that we don't care about for ESCI451
    if round_to:
        return round(result['s12'] / 1000., round_to)
    else:
        return result['s12'] / 1000.
コード例 #21
0
# Declarar bibliotecas--------------------------------------------------------------------------------------------

import os
import netCDF4
import numpy as np
import pandas as pd
from geographiclib.geodesic import Geodesic

# Definir os parâmetros do elipsoide TOPEX ---------------------------------------------------------------------------------------

a=6378136.300000 
b=6356751.600563
f=(a-b)/a
geod = Geodesic(a, f)

# Inserir os passes ------------------------------------------------------------------------------------------------

for escolha_passe in ['0239', '0228', '0163', '0152', '0076', '0050']:

    # Abrir os arquivos com extensão .nc e ler os dados--------------------------------------------------------------
    
    def dados_EOT(num):
        jday=[]
        jlon=[]
        jlat=[]
        jltide=[]
        jotide=[]
        missions=os.listdir('Link do diretório do Modelo EOT')
        for i in range(0,len(missions),1):
            print('Missão escolhida:',missions[i])
            link='Link do diretório do Modelo EOT/%s'%(missions[i])
コード例 #22
0
 def test_GeodSolve28(self):
     # Check for bad placement of assignment of r.a12 with |f| > 0.01 (bug in
     # Java implementation fixed on 2015-05-19).
     geod = Geodesic(6.4e6, 0.1)
     dir = geod.Direct(1, 2, 10, 5e6)
     self.assertAlmostEqual(dir["a12"], 48.55570690, delta=0.5e-8)
コード例 #23
0
 def test_GeodSolve26(self):
     # Check 0/0 problem with area calculation on sphere 2015-09-08
     geod = Geodesic(6.4e6, 0)
     inv = geod.Inverse(1, 2, 3, 4, Geodesic.AREA)
     self.assertAlmostEqual(inv["S12"], 49911046115.0, delta=0.5)
コード例 #24
0
 def test_GeodSolve15(self):
     # Initial implementation of Math::eatanhe was wrong for e^2 < 0.  This
     # checks that this is fixed.
     geod = Geodesic(6.4e6, -1 / 150.0)
     dir = geod.Direct(1, 2, 3, 4, Geodesic.AREA)
     self.assertAlmostEqual(dir["S12"], 23700, delta=0.5)
コード例 #25
0
            event.az = 253
            event.latitude = 15.09
            event.longitude = 179.59
        elif event.name == "S0325a":
            event.distance = 38.4
            event.baz = 0.0
            event.az = 180.0
            from geographiclib.geodesic import Geodesic

            radius = 3389.5
            flattening = 0.0

            dict = Geodesic(a=radius, f=flattening).ArcDirect(
                lat1=rec.latitude,
                lon1=rec.longitude,
                azi1=event.baz,
                a12=event.distance,
                outmask=1929,
            )
            event.latitude = dict["lat2"]
            event.longitude = dict["lon2"]
        """ Define forward modeler """
        forward_method = "INSTASEIS"
        # db_path = v["db_path"]
        # npz_file = v["npz_file"]
        db_nr = 0
        for db_path, npz_file in zip(db_names, npz_file_names):

            db_nr += 0
            # mnt_folder = "/mnt/marshost/"
            # if not lsdir(mnt_folder):
コード例 #26
0
Requirements:
    geographiclib==1.46.3
    pyproj==1.9.5.1
    geopy==1.11.0
    git+https://github.com/xoolive/geodesy@c4eb611cc225908872715f7558ca6a686271327a
'''
from math import radians, sin, cos, asin, sqrt, pi, atan, atan2, fabs
from time import time
import geopy.distance
import pyproj
from geographiclib.geodesic import Geodesic, Constants

import geodesy.sphere as geo

geod = pyproj.Geod(ellps='WGS84')
geodesic = Geodesic(a=Constants.WGS84_a, f=Constants.WGS84_f)

p_minsk = (27.561831, 53.902257)
p_moscow = (37.620393, 55.75396)

# https://en.wikipedia.org/wiki/Earth_radius#Mean_radius
EARTH_MEAN_RADIUS = 6371008.8
EARTH_MEAN_DIAMETER = 2 * EARTH_MEAN_RADIUS

# https://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius
EARTH_EQUATORIAL_RADIUS = 6378137.0
EARTH_EQUATORIAL_METERS_PER_DEGREE = pi * EARTH_EQUATORIAL_RADIUS / 180  # 111319.49079327358
I_EARTH_EQUATORIAL_METERS_PER_DEGREE = 1 / EARTH_EQUATORIAL_METERS_PER_DEGREE


def approximate_distance(point1, point2):
コード例 #27
0
Python geographiclib is also required:
pip install geographiclib


"""

import math
import pandas as pd
import matplotlib.pyplot as plt
from scipy.misc import imread

from geographiclib.geodesic import Geodesic

geod = Geodesic.WGS84
geod = Geodesic(6378388, 1/297.0) # the international ellipsoid

plt.style.use('ggplot')


def makemap(title):  # plot all the airports dots
    fig = plt.figure(figsize=(48,24))
    
    ax = fig.add_subplot(111)
    ax.set_title(title.decode('utf8'))
    ax.grid(b=False)
    for spine in ['left','right','top','bottom']:
        ax.spines[spine].set_color('k')
        
    img = imread("earthmap_hires.jpg")
    
コード例 #28
0
ファイル: localization.py プロジェクト: stevenlujpl/pdsc
class GeodesicLocalizer(Localizer):
    """
    The :py:class:`GeodesicLocalizer` is a type of localizer that is used when
    observation locations are described in terms of a center latitude/longitude
    and a line-of-flight direction. This localizer assumes that along-track
    pixels in the center column of the observaton roughly follow a geodesic path
    in the direction of flight and cross-track pixels in each row are
    perpendicular to this path.
    """

    BODY = Geodesic(MARS_RADIUS_M, MARS_FLATTENING)
    """
    A :py:class:`~geographiclib.geodesic.Geodesic` object describing the target
    body
    """

    def __init__(self, center_row, center_col, center_lat, center_lon,
            n_rows, n_cols, pixel_height_m, pixel_width_m,
            north_azimuth_deg, flight_direction=1):
        """
        :param center_row:
            the center row of the observation
        :param center_col:
            the center column of the observation
        :param center_lat:
            the latitude (in degrees) of the pixel at the center of the
            observation
        :param center_lat:
            the longitude (east, in degrees) of the pixel at the center of the
            observation
        :param n_rows:
            the total number of rows in the observation
        :param n_cols:
            the total number of columns in the observation
        :param pixel_height_m:
            the pixel height (in meters)
        :param pixel_width_m:
            the pixel width (in meters)
        :param north_azimuth_deg:
            the clockwise angle (in degrees) from a vector that points 90
            degrees counter-clockwise from the line-of-flight direction to north
        :param flight_direction:
            a multiplicative factor indicating the direction of flight relative
            to the :math:`y`-direction in pixel space; if
            ``flight_direction=1``, then the flight direction is from the the
            top down, whereas ``flight_direction=-1`` indicates a bottom-up
            direction of flight

        .. Note::
            If :py:attr:`~Localizer.NORMALIZED_PIXEL_SPACE` for this localizer
            is ``True``, then the pixel coordinates range from zero to one.
            Consequently, the attributes :py:attr:`~GeodesicLocalizer.n_cols`
            and :py:attr:`~GeodesicLocalizer.n_rows` are both equal to one, and
            the attributes :py:attr:`~GeodesicLocalizer.pixel_width_m` and
            :py:attr:`~GeodesicLocalizer.pixel_height_m` are both the width and
            height of the *entire* observation.
        """

        if n_rows <= 0: raise ValueError('No image rows')
        if n_cols <= 0: raise ValueError('No image columns')
        if pixel_height_m <= 0: raise ValueError('Negative pixel height')
        if pixel_width_m <= 0: raise ValueError('Negative pixel width')

        self.center_row = center_row
        self.center_col = center_col
        self.center_lat = center_lat
        self.center_lon = center_lon
        self.n_rows = n_rows
        self.n_cols = n_cols
        self.pixel_height_m = pixel_height_m
        self.pixel_width_m = pixel_width_m
        self.north_azimuth_deg = north_azimuth_deg
        self.flight_direction = flight_direction
        self._height = None
        self._width = None

    @property
    def observation_width_m(self):
        if self._width is None:
            self._width = self.pixel_width_m*self.n_cols
        return self._width

    @property
    def observation_length_m(self):
        if self._height is None:
            self._height = self.pixel_height_m*self.n_rows
        return self._height

    def pixel_to_latlon(self, row, col):
        x_m = (col - self.center_col) * self.pixel_width_m
        y_m = (row - self.center_row) * self.pixel_height_m
        y_m *= self.flight_direction

        flight_line_point = self.BODY.Direct(
            self.center_lat, self.center_lon,
            90 - self.north_azimuth_deg,
            y_m
        )

        cross_line_point = self.BODY.Direct(
            flight_line_point['lat2'],
            flight_line_point['lon2'],
            flight_line_point['azi2'] - 90,
            x_m
        )

        return cross_line_point['lat2'], cross_line_point['lon2']

    def location_mask(self, subsample_rows=10, subsample_cols=25,
            reinterpolate=True, verbose=False):
        """
        Compute a latitude and longitude for every pixel in an observation (with
        subsampling/reinterpolation to increase efficiency)

        :param subsample_rows: only compute location once every this many rows
        :param subsample_cols: only compute location once every this many
            columns
        :param reinterpolate: if subsampling is used, reinterpolate values for
            skipped pixels
        :param verbose: if ``True``, display a progress bar

        :return: a :py:class:`numpy.array` containing the latitude and east
            longitude (in degrees) along the last dimension for every pixel in
            the image, modulo subsampling

        .. Warning::
            This function is experimental and the reinterpolation step does not
            correctly handle discontinuities that arise near the "date line" or
            the poles.
        """
        nrows = int(np.ceil(self.n_rows // subsample_rows))
        ncols = int(np.ceil(self.n_cols // subsample_cols))

        progress = standard_progress_bar('Computing Location Mask', verbose)
        L = np.array([
            [self.pixel_to_latlon(r, c)
                for c in np.linspace(0, self.n_cols - 1, ncols)]
            for r in progress(np.linspace(0, self.n_rows - 1, nrows))
        ])
        if reinterpolate:
            zoom_factor = (
                float(self.n_rows) / L.shape[0],
                float(self.n_cols) / L.shape[1]
            )
            L = np.dstack([
                zoom(L[..., 0], zoom_factor, order=1, mode='nearest'),
                zoom(L[..., 1], zoom_factor, order=1, mode='nearest')
            ])
        return L
コード例 #29
0
ファイル: taup_geo.py プロジェクト: maratumba/obspy-gcfio
def add_geo_to_arrivals(arrivals, source_latitude_in_deg,
                        source_longitude_in_deg, receiver_latitude_in_deg,
                        receiver_longitude_in_deg, radius_of_earth_in_km,
                        flattening_of_earth):
    """
    Add geographical information to arrivals.

    :param arrivals: Set of taup arrivals
    :type: :class:`Arrivals`
    :param source_latitude_in_deg: Source location latitude in degrees
    :type source_latitude_in_deg: float
    :param source_longitude_in_deg: Source location longitude in degrees
    :type source_longitude_in_deg: float
    :param receiver_latitude_in_deg: Receiver location latitude in degrees
    :type receiver_latitude_in_deg: float
    :param receiver_longitude_in_deg: Receiver location longitude in degrees
    :type receiver_longitude_in_deg: float
    :param radius_of_earth_in_km: Radius of the Earth in km
    :type radius_of_earth_in_km: float
    :param flattening_of_earth: Flattening of Earth (0 for a sphere)
    :type receiver_longitude_in_deg: float

    :return: List of ``Arrival`` objects, each of which has the time,
        corresponding phase name, ray parameter, takeoff angle, etc. as
        attributes.
    :rtype: :class:`Arrivals`
    """
    if geodetics.HAS_GEOGRAPHICLIB:
        ellipsoid = Geodesic(a=radius_of_earth_in_km * 1000.0,
                             f=flattening_of_earth)
        g = ellipsoid.Inverse(source_latitude_in_deg, source_longitude_in_deg,
                              receiver_latitude_in_deg,
                              receiver_longitude_in_deg)
        azimuth = g['azi1']
        line = ellipsoid.Line(source_latitude_in_deg, source_longitude_in_deg,
                              azimuth)

        # We may need to update many arrival objects
        # and each could have pierce points and a
        # path
        for arrival in arrivals:

            if arrival.pierce is not None:
                geo_pierce = np.empty(arrival.pierce.shape, dtype=TimeDistGeo)
                for i, pierce_point in enumerate(arrival.pierce):
                    pos = line.ArcPosition(np.degrees(pierce_point['dist']))
                    geo_pierce[i] = (pierce_point['p'], pierce_point['time'],
                                     pierce_point['dist'],
                                     pierce_point['depth'],
                                     pos['lat2'], pos['lon2'])
                arrival.pierce = geo_pierce

            if arrival.path is not None:
                geo_path = np.empty(arrival.path.shape, dtype=TimeDistGeo)
                for i, path_point in enumerate(arrival.path):
                    pos = line.ArcPosition(np.degrees(path_point['dist']))
                    geo_path[i] = (path_point['p'], path_point['time'],
                                   path_point['dist'], path_point['depth'],
                                   pos['lat2'], pos['lon2'])
                arrival.path = geo_path

    else:
        # geographiclib is not installed ...
        # and  obspy/geodetics does not help much
        msg = "You need to install the Python module 'geographiclib' in " + \
              "order to add geographical information to arrivals."
        raise ImportError(msg)

    return arrivals
コード例 #30
0
    def run(self):
        """Run method that performs all the real work"""

        # show the dialog
        self.dlg.show()

        # set default values
        self.inLayer = self.dlg.mMapLayerComboBox.currentLayer()

        # set segmenting method
        self.segmentMethod = ''
        if self.dlg.spacingRadioButton.isChecked():
            self.segmentMethod = 'spacing'
        else:
            self.segmentMethod = 'count'

        def set_in_layer():
            """ function to set the input layer from the GUI """
            self.inLayer = self.dlg.mMapLayerComboBox.currentLayer()
            if self.inLayer:
                if self.inLayer.crs():
                    self.dlg.messageBox.setText("Input Layer Set: " +
                                                str(self.inLayer.name()))
                else:
                    self.dlg.messageBox.setText(
                        "Error: Input must have projection defined")

        # listener to set input layer when combo box changes
        self.dlg.mMapLayerComboBox.layerChanged.connect(set_in_layer)

        # clear the ellipsoid combobox
        self.dlg.EllipsoidcomboBox.clear()

        # this is a dictionary of common ellipsoid parameters
        # http://www.ga.gov.au/__data/assets/file/0019/11377/Vincentys-formulae-to-calculate-distance-and-bearing-from-latitude-and-longitude.xls
        ellipsoid_dict = {
            '165': [6378165.000, 298.3],
            'ANS': [6378160, 298.25],
            'CLARKE 1858': [6378293.645, 294.26],
            'GRS80': [6378137, 298.2572221],
            'WGS72': [6378135, 298.26],
            'International 1924': [6378388, 297],
            'WGS84': [6378137, 298.2572236]
        }

        # add items to ellipsoid combobox
        for k in list(ellipsoid_dict.keys()):
            self.dlg.EllipsoidcomboBox.addItem(str(k))

        # default ellipsoid is WGS84
        self.ellipsoid_a = 6378137.0
        self.ellipsoid_f = 298.2572236
        self.ellipsoid_name = 'WGS84'
        self.dlg.EllipsoidcomboBox.setCurrentText(self.ellipsoid_name)

        def set_in_ellipsoid():
            """ This function gets the ellipsoid name from the GUI and sets the parameters """
            in_ellipsoid_name = self.dlg.EllipsoidcomboBox.currentText()
            for k in list(ellipsoid_dict.keys()):
                if k == in_ellipsoid_name:
                    self.ellipsoid_a = ellipsoid_dict[k][0]
                    self.ellipsoid_f = ellipsoid_dict[k][1]
                    self.ellipsoid_name = k
                    self.dlg.messageBox.setText("Ellipsoid set to " + str(k))

        # listener to set input ellipsoid when combo box changes
        self.dlg.EllipsoidcomboBox.currentIndexChanged.connect(
            set_in_ellipsoid)

        # default is point spacing with 900m
        self.spacing = 900
        self.dlg.spacingSpinBox.setValue(self.spacing)
        self.dlg.spacingRadioButton.setChecked(True)

        # choose segment length
        def set_in_spacing():
            self.spacing = int(self.dlg.spacingSpinBox.value())
            self.dlg.messageBox.setText("Point spacing set to " +
                                        str(self.spacing) + "m")

        # listener to set input point spacing when spin box changes
        self.dlg.spacingSpinBox.valueChanged.connect(set_in_spacing)

        # default segment number is 10
        self.segmentCount = 10
        self.dlg.segmentsSpinBox.setValue(self.segmentCount)
        self.dlg.segmentsRadioButton.setChecked(False)

        # choose number of segments
        def set_in_segments():
            self.segmentCount = int(self.dlg.segmentsSpinBox.value())
            self.dlg.messageBox.setText("Segment count set to " +
                                        str(self.segmentCount))

        # listener to set input point spacing when spin box changes
        self.dlg.segmentsSpinBox.valueChanged.connect(set_in_segments)

        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            # set the input layer
            self.inLayer = self.dlg.mMapLayerComboBox.currentLayer()

            # set segmenting method
            self.segmentMethod = ''
            if self.dlg.spacingRadioButton.isChecked():
                self.segmentMethod = 'spacing'
            else:
                self.segmentMethod = 'count'

            # get the field list
            fields = self.inLayer.fields()

            # handle layers that aren't WGS84 (EPSG:4326)
            wgs84crs = QgsCoordinateReferenceSystem("EPSG:4326")
            if self.inLayer.crs() != wgs84crs:
                transtowgs84 = QgsCoordinateTransform(self.inLayer.crs(),
                                                      wgs84crs,
                                                      QgsProject.instance())
                transfromwgs84 = QgsCoordinateTransform(
                    wgs84crs, self.inLayer.crs(), QgsProject.instance())

            # get input geometry type
            self.inType = 'Unknown'
            if self.inLayer.geometryType() == QgsWkbTypes.PointGeometry:
                self.inType = 'Point'

            elif self.inLayer.geometryType() == QgsWkbTypes.LineGeometry:
                self.inType = 'LineString'

            elif self.inLayer.geometryType() == QgsWkbTypes.PolygonGeometry:
                self.inType = 'Polygon'

            else:
                self.iface.messageBar().pushWarning(
                    "Error", "geometry type not recognized")

            # setup output layers
            if self.inType == 'Point':
                self.create_point = True
                # create and add to map canvas a point memory layer
                layer_name = "Densified Point " + str(
                    self.ellipsoid_name) + " " + str(self.spacing) + "m"
                out_point_layer = self.iface.addVectorLayer(
                    "Point?crs={}".format(self.inLayer.crs().authid()),
                    layer_name, "memory")
                # set data provider
                provider = out_point_layer.dataProvider()
                # add attribute fields
                provider.addAttributes(fields)
                self.pointTypeField = ''
                for fieldName in ["pointType", "pntType", "pntTyp"]:
                    if fieldName not in [field.name() for field in fields]:
                        self.pointTypeField = fieldName
                provider.addAttributes(
                    [QgsField(self.pointTypeField, QVariant.String)])
                out_point_layer.updateFields()
            else:
                self.create_point = False

            if self.inType == 'LineString':
                self.create_polyline = True
                # create and add to map canvas a polyline memory layer
                layer_name = "Densified Line " + str(
                    self.ellipsoid_name) + " " + str(self.spacing) + "m"
                out_line_layer = self.iface.addVectorLayer(
                    "LineString?crs={}".format(self.inLayer.crs().authid()),
                    layer_name, "memory")
                # set data provider
                provider = out_line_layer.dataProvider()
                # add attribute fields
                provider.addAttributes(fields)
                out_line_layer.updateFields()
            else:
                self.create_polyline = False

            if self.inType == 'Polygon':
                self.create_polygon = True
                # create and add to map canvas a polyline memory layer
                layer_name = "Densified Polygon " + str(
                    self.ellipsoid_name) + " " + str(self.spacing) + "m"
                out_poly_layer = self.iface.addVectorLayer(
                    "Polygon?crs={}".format(self.inLayer.crs().authid()),
                    layer_name, "memory")
                # set data provider
                provider = out_poly_layer.dataProvider()
                # add attribute fields
                provider.addAttributes(fields)
                out_poly_layer.updateFields()
            else:
                self.create_polygon = False

            # Create a geographiclib Geodesic object
            self.geod = Geodesic(self.ellipsoid_a, 1 / self.ellipsoid_f)

            def densify_point(in_layer, pr):
                """ This function densifies the input point layer and writes it to the output provider"""
                # iterator to read input layer
                iterator = in_layer.getFeatures()
                # counter to mark first point as "original"
                counter = 0
                # empty feature used to store temporary data
                current_feature = QgsFeature()
                # counter to report features that don't work
                bad_geom = 0
                for feature in iterator:
                    if not feature.geometry().isMultipart():
                        try:
                            if counter == 0:
                                # this is only for the first point
                                pointxy = feature.geometry().asPoint()
                                current_feature.setGeometry(
                                    QgsGeometry.fromPointXY(pointxy))
                                attr = feature.attributes()
                                attr.append("Original")
                                current_feature.setAttributes(attr)
                                pr.addFeatures([current_feature])
                            else:
                                start_pt = current_feature.geometry().asPoint()
                                end_pt = feature.geometry().asPoint()
                                if self.inLayer.crs() != wgs84crs:
                                    start_pt = transtowgs84.transform(start_pt)
                                    end_pt = transtowgs84.transform(end_pt)
                                # create a geographiclib line object
                                line_object = self.geod.InverseLine(
                                    start_pt.y(), start_pt.x(), end_pt.y(),
                                    end_pt.x())
                                # determine how many densified segments there will be
                                if self.segmentMethod == 'count':
                                    n = self.segmentCount
                                else:
                                    n = int(
                                        math.ceil(line_object.s13 /
                                                  self.spacing))
                                # adjust the spacing distance
                                seglen = line_object.s13 / n
                                # create densified points along the line object
                                for i in range(1, n):
                                    if i > 0:
                                        s = seglen * i
                                        g = line_object.Position(
                                            s, Geodesic.LATITUDE
                                            | Geodesic.LONGITUDE
                                            | Geodesic.LONG_UNROLL)
                                        geom = QgsPointXY(g['lon2'], g['lat2'])
                                        attr = feature.attributes()
                                        attr.append("Densified")
                                        current_feature.setAttributes(attr)
                                        if self.inLayer.crs(
                                        ) != wgs84crs:  # Convert each point back to the output CRS
                                            geom = transfromwgs84.transform(
                                                geom)
                                        current_feature.setGeometry(
                                            QgsGeometry.fromPointXY(geom))
                                        # write the point
                                        pr.addFeatures([current_feature])
                                # write the last point
                                geom = feature.geometry().asPoint()
                                current_feature.setGeometry(
                                    QgsGeometry.fromPointXY(geom))
                                attr = feature.attributes()
                                attr.append("Original")
                                current_feature.setAttributes(attr)
                                pr.addFeatures([current_feature])
                            counter += 1
                        except:
                            bad_geom += 1
                            counter += 1
                    else:
                        bad_geom += 1
                        self.iface.messageBar().pushWarning(
                            "error",
                            "multipoint geometries will not be densified")
                if bad_geom > 0:
                    # report number of features that didn't work
                    self.iface.messageBar().pushWarning(
                        "Error", "{} features failed".format(bad_geom))

            def densify_poly(in_layer, pr):
                bad_geom = 0
                iterator = in_layer.getFeatures()
                # create empty feature to write to
                for feature in iterator:
                    try:
                        if feature.geometry().wkbType(
                        ) == QgsWkbTypes.LineString:
                            line_geom = feature.geometry().asPolyline()
                            geom_type = "LineString"
                        elif feature.geometry().wkbType(
                        ) == QgsWkbTypes.MultiLineString:
                            multiline_geom = feature.geometry(
                            ).asMultiPolyline()
                            geom_type = "MultiLineString"
                        elif feature.geometry().wkbType(
                        ) == QgsWkbTypes.Polygon:
                            poly_geom = feature.geometry().asPolygon()
                            geom_type = "Polygon"
                        elif feature.geometry().wkbType(
                        ) == QgsWkbTypes.MultiPolygon:
                            multipoly_geom = feature.geometry().asMultiPolygon(
                            )
                            geom_type = "MultiPolygon"
                        else:
                            bad_geom += 1
                    except:
                        bad_geom += 1

                    if geom_type == "LineString":
                        dense_points = []
                        point_count = len(line_geom)
                        start_pt = QgsPointXY(line_geom[0][0], line_geom[0][1])
                        dense_points.append(start_pt)
                        if self.inLayer.crs() != wgs84crs:
                            start_pt = transtowgs84.transform(start_pt)
                        for j in range(1, point_count):
                            end_pt = QgsPointXY(line_geom[j][0],
                                                line_geom[j][1])
                            if self.inLayer.crs() != wgs84crs:
                                end_pt = transtowgs84.transform(end_pt)
                            # create a geographiclib line object
                            line_object = self.geod.InverseLine(
                                start_pt.y(), start_pt.x(), end_pt.y(),
                                end_pt.x())
                            # determine how many densified segments there will be
                            if self.segmentMethod == 'count':
                                n = self.segmentCount
                            else:
                                n = int(
                                    math.ceil(line_object.s13 / self.spacing))
                            if line_object.s13 > self.spacing:
                                seglen = line_object.s13 / n
                                for k in range(1, n):
                                    s = seglen * k
                                    g = line_object.Position(
                                        s,
                                        Geodesic.LATITUDE | Geodesic.LONGITUDE
                                        | Geodesic.LONG_UNROLL)
                                    waypoint = QgsPointXY(g['lon2'], g['lat2'])
                                    if self.inLayer.crs() != wgs84crs:
                                        waypoint = transfromwgs84.transform(
                                            waypoint)
                                    dense_points.append(waypoint)
                                if self.inLayer.crs() != wgs84crs:
                                    end_pt = transfromwgs84.transform(end_pt)
                                dense_points.append(end_pt)
                            start_pt = end_pt

                    elif geom_type == "MultiLineString":
                        dense_features = []
                        for i in range(len(multiline_geom)):
                            dense_points = []
                            line = multiline_geom[i]
                            point_count = len(line)
                            start_pt = QgsPointXY(line[0][0], line[0][1])
                            dense_points.append(start_pt)
                            for j in range(1, point_count):
                                end_pt = QgsPointXY(line[j][0], line[j][1])
                                if self.inLayer.crs() != wgs84crs:
                                    start_pt = transtowgs84.transform(start_pt)
                                    end_pt = transtowgs84.transform(end_pt)
                                # create a geographiclib line object
                                line_object = self.geod.InverseLine(
                                    start_pt.y(), start_pt.x(), end_pt.y(),
                                    end_pt.x())
                                # determine how many densified segments there will be
                                if self.segmentMethod == 'count':
                                    n = self.segmentCount
                                else:
                                    n = int(
                                        math.ceil(line_object.s13 /
                                                  self.spacing))
                                if line_object.s13 > self.spacing:
                                    seglen = line_object.s13 / n
                                    for k in range(1, n):
                                        s = seglen * k
                                        g = line_object.Position(
                                            s, Geodesic.LATITUDE
                                            | Geodesic.LONGITUDE
                                            | Geodesic.LONG_UNROLL)
                                        waypoint = QgsPointXY(
                                            g['lon2'], g['lat2'])
                                        if self.inLayer.crs() != wgs84crs:
                                            waypoint = transfromwgs84.transform(
                                                waypoint)
                                        dense_points.append(waypoint)
                                    if self.inLayer.crs() != wgs84crs:
                                        end_pt = transfromwgs84.transform(
                                            end_pt)
                                    dense_points.append(end_pt)
                                start_pt = end_pt
                            dense_features.append(dense_points)

                    elif geom_type == "Polygon":
                        for poly in poly_geom:
                            dense_points = []
                            point_count = len(poly)
                            start_pt = QgsPointXY(poly[0][0], poly[0][1])
                            dense_points.append(start_pt)
                            for j in range(1, point_count):
                                end_pt = QgsPointXY(poly[j][0], poly[j][1])
                                if self.inLayer.crs() != wgs84crs:
                                    end_pt = transtowgs84.transform(end_pt)
                                    start_pt = transtowgs84.transform(start_pt)
                                # create a geographiclib line object
                                line_object = self.geod.InverseLine(
                                    start_pt.y(), start_pt.x(), end_pt.y(),
                                    end_pt.x())
                                # determine how many densified segments there will be
                                if self.segmentMethod == 'count':
                                    n = self.segmentCount
                                else:
                                    n = int(
                                        math.ceil(line_object.s13 /
                                                  self.spacing))
                                if line_object.s13 > self.spacing:
                                    seglen = line_object.s13 / n
                                    for k in range(1, n):
                                        s = seglen * k
                                        g = line_object.Position(
                                            s, Geodesic.LATITUDE
                                            | Geodesic.LONGITUDE
                                            | Geodesic.LONG_UNROLL)
                                        waypoint = QgsPointXY(
                                            g['lon2'], g['lat2'])
                                        if self.inLayer.crs() != wgs84crs:
                                            waypoint = transfromwgs84.transform(
                                                waypoint)
                                        dense_points.append(waypoint)
                                    if self.inLayer.crs() != wgs84crs:
                                        end_pt = transfromwgs84.transform(
                                            end_pt)
                                    dense_points.append(end_pt)
                                start_pt = end_pt

                    if geom_type == "MultiPolygon":
                        dense_features = []
                        for i in range(len(multipoly_geom)):
                            dense_points = []
                            poly = multipoly_geom[i][0]
                            point_count = len(poly)
                            start_pt = QgsPointXY(poly[0][0], poly[0][1])
                            dense_points.append(start_pt)
                            for j in range(1, point_count):
                                end_pt = QgsPointXY(poly[j][0], poly[j][1])
                                if self.inLayer.crs() != wgs84crs:
                                    start_pt = transtowgs84.transform(start_pt)
                                    end_pt = transtowgs84.transform(end_pt)
                                # create a geographiclib line object
                                line_object = self.geod.InverseLine(
                                    start_pt.y(), start_pt.x(), end_pt.y(),
                                    end_pt.x())
                                # determine how many densified segments there will be
                                if self.segmentMethod == 'count':
                                    n = self.segmentCount
                                else:
                                    n = int(
                                        math.ceil(line_object.s13 /
                                                  self.spacing))
                                if line_object.s13 > self.spacing:
                                    seglen = line_object.s13 / n
                                    for k in range(1, n):
                                        s = seglen * k
                                        g = line_object.Position(
                                            s, Geodesic.LATITUDE
                                            | Geodesic.LONGITUDE
                                            | Geodesic.LONG_UNROLL)
                                        waypoint = QgsPointXY(
                                            g['lon2'], g['lat2'])
                                        if self.inLayer.crs() != wgs84crs:
                                            waypoint = transfromwgs84.transform(
                                                waypoint)
                                        dense_points.append(waypoint)
                                    if self.inLayer.crs() != wgs84crs:
                                        end_pt = transfromwgs84.transform(
                                            end_pt)
                                    dense_points.append(end_pt)
                                start_pt = end_pt
                            dense_features.append(dense_points)

                    new_poly = QgsFeature()
                    if geom_type == "LineString":
                        new_poly.setGeometry(
                            QgsGeometry.fromPolylineXY(dense_points))
                    elif geom_type == "MultiLineString":
                        new_poly.setGeometry(
                            QgsGeometry.fromMultiPolylineXY(dense_features))
                    elif geom_type == "Polygon":
                        new_poly.setGeometry(
                            QgsGeometry.fromPolygonXY([dense_points]))
                    elif geom_type == "MultiPolygon":
                        new_poly.setGeometry(
                            QgsGeometry.fromMultiPolygonXY([dense_features]))
                    new_poly.setAttributes(feature.attributes())
                    pr.addFeatures([new_poly])
                if bad_geom > 0:
                    self.iface.messageBar().pushWarning(
                        "", "{} features failed".format(bad_geom))

            if self.create_point:
                densify_point(self.inLayer, provider)
                out_point_layer.reload()

            if self.create_polyline:
                densify_poly(self.inLayer, provider)
                out_line_layer.reload()

            if self.create_polygon:
                densify_poly(self.inLayer, provider)
                out_poly_layer.reload()