Ejemplo n.º 1
0
def merge_polygons(polygons,rotation_model,
                   time=0,sampling=1.,area_threshold=None,filename=None,
                   return_raster=False):

    multipoints = create_gpml_regular_long_lat_mesh(sampling)
    grid_dims = (int(180/sampling)+1,int(360/sampling)+1)

    for multipoint in multipoints:
        for mp in multipoint.get_all_geometries():
            points = mp.to_lat_lon_point_list()

    bi = run_grid_pip(time,points,polygons,rotation_model,grid_dims)
    
    if return_raster:
        return bi
    
    else:
        # To handle edge effects, pad grid before making contour polygons  
        ## --- start
        pad_hor = np.zeros((1,bi.shape[1]))
        pad_ver = np.zeros((bi.shape[0]+2,1))
        pad1 = np.vstack((pad_hor,bi,pad_hor))      # add row of zeros to top and bottom
        pad2 = np.hstack((pad_ver,pad1,pad_ver))    # add row of zeros to left and right
        #pad3 = np.hstack((pad2,pad_ver))
        contours = measure.find_contours(pad2, 0.5, fully_connected='low')
        ## --- end
    
        contour_polygons = []
        contour_features = []
    
        for n,cp in enumerate(contours):
        
            # To handle edge effects again - strip off parts of polygon
            # due to padding, and adjust from image coordinates to long/lat
            # --- start
            cp[:,1] = (cp[:,1]*sampling)-sampling
            cp[:,0] = (cp[:,0]*sampling)-sampling
            cp[np.where(cp[:,0]<0.),0] = 0
            cp[np.where(cp[:,0]>180.),0] = 180
            cp[np.where(cp[:,1]<0.),1] = 0
            cp[np.where(cp[:,1]>360.),1] = 360
            ## --- end
        
            cpf = pygplates.PolygonOnSphere(zip(cp[:,0]-90,cp[:,1]-180))
            contour_polygons.append(cpf)
        
            feature = pygplates.Feature()
            feature.set_geometry(cpf)
            contour_features.append(feature)

        if filename is not None:
            pygplates.FeatureCollection(contour_features).write(filename)

        else:
            return contour_features
def check_points_within_polygon(lons, lats, polygon_points):
    polygon = pygplates.PolygonOnSphere(
        zip(polygon_points[1::2], polygon_points[::2]))
    ret = []
    for lon, lat in zip(lons, lats):
        #print(lon,lat)
        try:
            if polygon.is_point_in_polygon((lat, lon)):
                ret.append(True)
            else:
                ret.append(False)
        except:
            ret.append(False)
    return ret
def grdcontour2feature(grdfile,clevel,return_polygons=True):

    # call GMT to get a single contour at the specified value of clevel
    call_system_command(['gmt',
                         'grdcontour',
                         grdfile,
                         '-Rd',
                         '-C+%0.8f' % clevel,
                         '-S4',
                         '-Dcontour_%c.txt'])

    # read in the GMT delimited xyz ascii file, 
    # create a list of lists with polygon coordinates
    f = open('./contour_C.txt', 'r')

    polygons = []
    contourlist = []
    for line in f:
        if line[0] == '>':
            if len(contourlist)>0:
                polygons.append(contourlist)
            contourlist = []
        else:
            line = line.split()
            contourlist.append([float(j) for j in line])
            #break

    # create gplates-format features
    polyline_features = []
    for p in polygons:
        pf = pygplates.PolylineOnSphere(zip(list(zip(*p))[1],list(zip(*p))[0]))
        polyline_features.append(pf)

    # use join to handle polylines split across dateline
    joined_polyline_features = pygplates.PolylineOnSphere.join(polyline_features)

    if return_polygons:
    # force polylines to be polygons
        joined_polygon_features = []
        for geom in joined_polyline_features:
            polygon = pygplates.Feature()
            polygon.set_geometry(pygplates.PolygonOnSphere(geom))
            joined_polygon_features.append(polygon)
            
        return joined_polygon_features

    else:
        return joined_polyline_features
Ejemplo n.º 4
0
def force_polygon_geometries(input_features):
# given any pygplates feature collection, creates an output feature collection
# where all geometries are polygons based on the input geometries
# intended for use in forcing features that are strictly polylines to close

    polygons = []
    for feature in input_features: 
        for geom in feature.get_all_geometries():
            polygon = pygplates.Feature()
            polygon.set_geometry(pygplates.PolygonOnSphere(geom))
            polygon.set_reconstruction_plate_id(feature.get_reconstruction_plate_id())
            # some features in COBTerranes had invalid time ranges - these with throw an error if 
            # we try to create a new feature with same times
            if feature.get_valid_time()[0]>=feature.get_valid_time()[1]:
                polygon.set_valid_time(feature.get_valid_time()[0],feature.get_valid_time()[1])
                polygons.append(polygon)
    polygon_features = pygplates.FeatureCollection(polygons)

    return polygon_features
Ejemplo n.º 5
0
def seds_filter_points_in_polygon(latitude, longitude, zvalue,
                                  reconstructed_coastlines):
    '''
    This function returns the plateID of latitude/longitude points
    at a given time from a rotation file

    It uses the topological plate boundary network to assign a plate ID.
    So it needs pyGPlates.
    '''

    #because of how the data is formatted we need two for loops to check each point
    #because we are loading in a 2d array of longitude and latitude *each*

    filtered_lats = []
    filtered_lons = []
    filtered_zvals = []

    for x, y, z in itertools.izip(latitude, longitude, zvalue):

        inputlatLon = pygplates.LatLonPoint(x, y)

        latLonPoint = pygplates.convert_lat_lon_point_to_point_on_sphere(
            inputlatLon)
        #print latLonPoint

        isPoly = []
        #get geometry of static polygons at reconstructed time
        for coastline in reconstructed_coastlines:
            #print coastline
            coastline = pygplates.PolygonOnSphere(
                coastline.get_reconstructed_geometry())
            #if int(coastline.is_point_in_polygon(latLonPoint)) == 1:
            #break#print tmp
            tmp = int(coastline.is_point_in_polygon(latLonPoint))
            isPoly.append(tmp)
        if np.sum(isPoly) == 0:

            filtered_lats.append(x)
            filtered_lons.append(y)
            filtered_zvals.append(z)

    return filtered_lats, filtered_lons, filtered_zvals
Ejemplo n.º 6
0
def reconstruct_coastlines(time):
    shp_path = settings.MODEL_STORE_DIR+'/'+settings.MODEL_DEFAULT+'/coastlines_low_res/Seton_etal_ESR2012_Coastlines_2012.shp'

    import shapefile
    sf = shapefile.Reader(shp_path)
    features = []
    for record in sf.shapeRecords():
        if record.shape.shapeType != 5:
            continue
        for idx in range(len(record.shape.parts)):
            start_idx = record.shape.parts[idx]
            end_idx = len(record.shape.points)
            if idx < (len(record.shape.parts) -1):
                end_idx = record.shape.parts[idx+1]
            polygon_feature = pygplates.Feature()
            points = record.shape.points[start_idx:end_idx]
            polygon_feature.set_geometry(
                pygplates.PolygonOnSphere([(lat,lon) for lon, lat in points]))
            polygon_feature.set_reconstruction_plate_id(int(record.record[0]))
            features.append(polygon_feature)
            break

    feature_collection = pygplates.FeatureCollection(features)
    reconstructed_polygons = []

    model_dict = get_reconstruction_model_dict(settings.MODEL_DEFAULT)
    rotation_model = pygplates.RotationModel([str('%s/%s/%s' %
        (settings.MODEL_STORE_DIR,settings.MODEL_DEFAULT,rot_file)) for rot_file in model_dict['RotationFile']])


    pygplates.reconstruct(
        feature_collection,
        rotation_model,
        reconstructed_polygons,
        float(time))

    return reconstructed_polygons
    def _create_node(self, node_centre_lon, node_centre_lat,
                     node_half_width_degrees, is_north_hemisphere):

        # Create the points of the polygon bounding the current quad tree node.

        bounding_polygon_points = []

        left_lon = node_centre_lon - node_half_width_degrees

        right_lon = node_centre_lon + node_half_width_degrees

        bottom_lat = node_centre_lat - node_half_width_degrees

        top_lat = node_centre_lat + node_half_width_degrees

        # Northern and southern hemispheres handled separately.

        if is_north_hemisphere:

            # Northern hemisphere.

            left_boundary = pygplates.PolylineOnSphere([(0, left_lon),
                                                        (90, left_lon)])

            right_boundary = pygplates.PolylineOnSphere([(0, right_lon),
                                                         (90, right_lon)])

            # Midpoint of small circle arc bounding the bottom of quad tree node.

            bottom_mid_point = pygplates.PointOnSphere(
                bottom_lat, 0.5 * (left_lon + right_lon))

            # Find the great circle (rotation) that passes through the bottom midpoint (and is oriented towards North pole).

            bottom_great_circle_rotation_axis = pygplates.Vector3D.cross(
                bottom_mid_point.to_xyz(),
                pygplates.Vector3D.cross(
                    pygplates.PointOnSphere.north_pole.to_xyz(),
                    bottom_mid_point.to_xyz())).to_normalised()

            bottom_great_circle_rotation = pygplates.FiniteRotation(
                bottom_great_circle_rotation_axis.to_xyz(), 0.5 * math.pi)

            # Intersect great circle bottom boundary with left and right boundaries to find bottom-left and bottom-right points.

            # The bottom boundary is actually a small circle (due to lat/lon grid), but since we need to use *great* circle arcs

            # in our geometries we need to be a bit loose with our bottom boundary otherwise it will go inside the quad tree node.

            bottom_boundary = pygplates.PolylineOnSphere([
                bottom_great_circle_rotation * bottom_mid_point,
                bottom_mid_point,
                bottom_great_circle_rotation.get_inverse() * bottom_mid_point
            ])

            _, _, bottom_left_point = pygplates.GeometryOnSphere.distance(
                bottom_boundary, left_boundary, return_closest_positions=True)

            _, _, bottom_right_point = pygplates.GeometryOnSphere.distance(
                bottom_boundary, right_boundary, return_closest_positions=True)

            bounding_polygon_points.append(bottom_left_point)

            bounding_polygon_points.append(bottom_right_point)

            bounding_polygon_points.append(
                pygplates.PointOnSphere(top_lat, right_lon))

            bounding_polygon_points.append(
                pygplates.PointOnSphere(top_lat, left_lon))

        else:

            # Southern hemisphere.

            left_boundary = pygplates.PolylineOnSphere([(0, left_lon),
                                                        (-90, left_lon)])

            right_boundary = pygplates.PolylineOnSphere([(0, right_lon),
                                                         (-90, right_lon)])

            # Midpoint of small circle arc bounding the top of quad tree node.

            top_mid_point = pygplates.PointOnSphere(
                top_lat, 0.5 * (left_lon + right_lon))

            # Find the great circle (rotation) that passes through the top midpoint (and is oriented towards North pole).

            top_great_circle_rotation_axis = pygplates.Vector3D.cross(
                top_mid_point.to_xyz(),
                pygplates.Vector3D.cross(
                    pygplates.PointOnSphere.north_pole.to_xyz(),
                    top_mid_point.to_xyz())).to_normalised()

            top_great_circle_rotation = pygplates.FiniteRotation(
                top_great_circle_rotation_axis.to_xyz(), 0.5 * math.pi)

            # Intersect great circle top boundary with left and right boundaries to find top-left and top-right points.

            # The top boundary is actually a small circle (due to lat/lon grid), but since we need to use *great* circle arcs

            # in our geometries we need to be a bit loose with our top boundary otherwise it will go inside the quad tree node.

            top_boundary = pygplates.PolylineOnSphere([
                top_great_circle_rotation * top_mid_point, top_mid_point,
                top_great_circle_rotation.get_inverse() * top_mid_point
            ])

            _, _, top_left_point = pygplates.GeometryOnSphere.distance(
                top_boundary, left_boundary, return_closest_positions=True)

            _, _, top_right_point = pygplates.GeometryOnSphere.distance(
                top_boundary, right_boundary, return_closest_positions=True)

            bounding_polygon_points.append(top_left_point)

            bounding_polygon_points.append(top_right_point)

            bounding_polygon_points.append(
                pygplates.PointOnSphere(bottom_lat, right_lon))

            bounding_polygon_points.append(
                pygplates.PointOnSphere(bottom_lat, left_lon))

        bounding_polygon = pygplates.PolygonOnSphere(bounding_polygon_points)

        return QuadTreeNode(bounding_polygon)
def get_area_in_band(polygon, lat_min, lat_max):
    """
    Calculate the area of a given polygon inside a given latitude band.

    Parameters
    ----------
    polygon : pygpplates polygon
    lat_min : float
        the minimum latitude of the latitude band
    lat_max : float
        the maximum latitude of the latitude band

    Returns
    -------
    area : float
        the area of the polygon within the latitude band (in km^2)
    band_polygon : pygplates polygon
        with the parts outside of the latitude band removed
    """
    # pull out lat/lon vertices
    lat_lon_array = polygon.to_lat_lon_array()
    lats = lat_lon_array[:, 0]
    lons = lat_lon_array[:, 1]

    # storage lists
    bookmarks = []
    lat_add_list = []
    lon_add_list = []

    # iterate through the points
    for i in range(1, len(lats)):
        top_cross = False
        bot_cross = False

        # case where we move into the band from above
        if lats[i - 1] > lat_max and lats[i] < lat_max:
            top_cross = True
        # case where we move out of the band from below
        if lats[i - 1] < lat_max and lats[i] > lat_max:
            top_cross = True
        # case where we move out of the band from above
        if lats[i - 1] > lat_min and lats[i] < lat_min:
            bot_cross = True
        # case where we move into the band from below
        if lats[i - 1] < lat_min and lats[i] > lat_min:
            bot_cross = True

        # do calculations if we cross
        if top_cross or bot_cross:

            # convert the endpoints of the polygon segment into cartesian
            A = lat_lon_2_cart(lats[i - 1], lons[i - 1])
            B = lat_lon_2_cart(lats[i], lons[i])

            # get the intersection point (for the top and bottom cases), and convert back to lat/lon
            if top_cross:
                C_top = lat_lon_2_cart(lat_max, min([lons[i], lons[i - 1]]))
                D_top = lat_lon_2_cart(lat_max, max([lons[i], lons[i - 1]]))
                T = intersection(A, B, C_top, D_top)
            else:
                C_bot = lat_lon_2_cart(lat_min, min([lons[i], lons[i - 1]]))
                D_bot = lat_lon_2_cart(lat_min, max([lons[i], lons[i - 1]]))
                T = intersection(A, B, C_bot, D_bot)
            lat_add, lon_add = cart_2_lat_lon(T)

            # add to the storage lists
            bookmarks.append(i)
            lat_add_list.append(lat_add)
            lon_add_list.append(lon_add)

    # now insert the stored values into the original arrays
    new_lats = np.insert(lats, bookmarks, lat_add_list)
    new_lons = np.insert(lons, bookmarks, lon_add_list)

    # only keep values below the maximum latitude (with small buffer)
    mask = np.less(new_lats, lat_max + 0.1)
    new_lats = new_lats[mask]
    new_lons = new_lons[mask]

    # only keep values above the minimum latitude
    mask = np.greater(new_lats, lat_min - 0.1)
    new_lats = new_lats[mask]
    new_lons = new_lons[mask]

    # create a Polygon, if we are left with enough points
    if len(new_lats) >= 3:
        band_polygon = pygplates.PolygonOnSphere(zip(new_lats, new_lons))

        # get the area in km2
        area = band_polygon.get_area() * 6371.009**2

    # if we don't...
    else:
        area = 0
        band_polygon = None

    return area, band_polygon
def subLoop(recsSub,shapesSub,fieldsSub,NshpSub,recsTopo,shapesTopo,fieldsTopo,NshpTopo,isright):
    '''
    Determines the overriding and subducting plate ID along a trench.
    Takes the subduction zone and plate polygon shapefile data as input.
    Returns a list of points of the form [Lon, Lat, SPid, TRENCHid, OPid]
    And puts some header information indicated by '>' for each subduction segment.
    '''
    #Initiialise the output array: [lon, lat, SPid, TRENCHid, OPid] 
    testingArray=[]
    FinalArray=[]
    
    #Go through subduction zones 1 by 1
    #print "Subdction zone number in file, and PlateID:"
    #NshpSub=[8,9]
    for nshpSub in xrange(NshpSub):
        
        #Get the Lat Lon points along the trench
        shapeArray=shapesSub[nshpSub].points
        
        #Reverse the order of LH arrays so convergence is +ve        
        reversedSub=0
        if not isright:
            #print "Reversing, LH array"
            shapeArray=shapeArray[::-1]
            reversedSub=1
        
        #Get the Trench ID and Time
        # Note this section looks both for a PLATE_ID and a PLATEID1 field for the trench
        # index, due to changes between different GPlates versions. If both are present for
        # some reason, the TRENCHid would be taken from the second one to be encountered
        for i in range(len(fieldsSub)):
            if 'PLATE_ID' in fieldsSub[i]:
                TRENCHidIndex = i-1
            elif 'PLATEID1' in fieldsSub[i]:
                TRENCHidIndex = i-1
            elif 'TIME' in fieldsSub[i]:
                TimeIndex = i-1
            elif 'FEATURE_ID' in fieldsSub[i]:
                GplatesTagIndex = i-1
            elif 'NAME' in fieldsSub[i]:
                NameIndex = i-1

        #Get the Trench ID and Time
        TRENCHid=recsSub[nshpSub][TRENCHidIndex] #3 new, 0 old (GPlates 1.2)        
        Time=recsSub[nshpSub][TimeIndex] #2 old
        GplatesTag=recsSub[nshpSub][GplatesTagIndex]
        name=recsSub[nshpSub][NameIndex]
        #print nshpSub,TRENCHid,GplatesTag,name


        #Store the Lat and Lon in seperate arrays, remove end points because 
        #they are prone to errors and confusing triple junctions!
        shapeArrayLon = [round(i[0],4) for i in shapeArray[:]]
        shapeArrayLat = [round(i[1],4) for i in shapeArray[:]]
        
        shapeArray=zip(shapeArrayLon,shapeArrayLat)

        #Append some header information
        #NPB!!! This is currently not used for much
        FinalArray.append(['> Name:' , name])
        FinalArray.append(['> GplatesTag:' , GplatesTag])
        FinalArray.append(['> PlateId:' , TRENCHid])
        FinalArray.append(['> Age:' , Time])
        FinalArray.append(['> Begin:' , 0])
        FinalArray.append(['> End:' , 0])
        FinalArray.append(['> Type:' , 0])
        FinalArray.append(['> Polygon:' , 0])
        FinalArray.append(['> Reversed:' , reversedSub])
        FinalArray.append(['> BoundaryPoints:' , len(shapeArray)])
        
        #Now we must loop through every point along the subduction zone and
        #check the polygons that it is attached to.
        for index, point in enumerate(shapeArray):
            OPcount=0
            SPcount=0
            for nshpTopo in xrange(NshpTopo):   
                #Get the Lat Lon points of the plate polygon
                topoArray=shapesTopo[nshpTopo].points

                #Store the Lat and Lon in seperate arrays
                topoArrayLon = [round(i[0],4) for i in topoArray]
                topoArrayLat = [round(i[1],4) for i in topoArray]

                topoArray=zip(topoArrayLon,topoArrayLat)
                
                #topoArray=numpy.around(shapesTopo[nshpTopo].points,decimals=5)
                
                #Test whether the subduction point is in the current
                #polygon. If it is, we can find out more information...
                try:
                    i = topoArray.index(point)
                    pointFlag = 1
                except:
                    pointFlag = 0
                
                #########################################
                #Now if the point exists on the polygon #
                #Let's find out whether it is OP or SP  #
                #########################################
                if pointFlag == 1:
                    #Get the PLATEid of the polygon (same comment as above - looks for field called either PLATE_ID or PLATEID1)
                    for i in range(len(fieldsTopo)):
                        if 'PLATE_ID' in fieldsTopo[i]:
                            PlateIndex = i-1
                        elif 'PLATEID1' in fieldsTopo[i]:
                            PlateIndex = i-1
                    PLATEid=recsTopo[nshpTopo][PlateIndex] #3 new, 0 old (GPlates 1.2) 

                    #Now get the entire polygon as a pygplates entitiy
                    latlonPoints=[]
                    for latlon in topoArray:
                        pointLatLon = pygplates.LatLonPoint(latlon[1],latlon[0])
                        latlonPoints.append(pygplates.convert_lat_lon_point_to_point_on_sphere(pointLatLon))

                    polygon = pygplates.PolygonOnSphere(latlonPoints)
                                        
                    #Convert our trench segment to pygplates format
                    if index < len(shapeArray)-1:
                        latPoint1 = shapeArray[index][1]
                        lonPoint1 = shapeArray[index][0]
                        pointXYZ, pointXYZcart = latlon2pygplates(latPoint1,lonPoint1)
                    
                        latPoint2 = shapeArray[index+1][1]
                        lonPoint2 = shapeArray[index+1][0]
                        pointXYZ2, pointXYZcart2 = latlon2pygplates(latPoint2,lonPoint2)
                    #If we are at the last trench segment, just jump back a point
                    else:
                        latPoint1 = shapeArray[index-1][1]
                        lonPoint1 = shapeArray[index-1][0]
                        pointXYZ, pointXYZcart = latlon2pygplates(latPoint1,lonPoint1)

                        latPoint2 = shapeArray[index][1]
                        lonPoint2 = shapeArray[index][0]
                        pointXYZ2, pointXYZcart2 = latlon2pygplates(latPoint2,lonPoint2)

                        
                    #Find the vector between 2 points on the trench
                    line = pygplates.PolylineOnSphere([pointXYZ,pointXYZ2])

                    #Find the midpoint between those two points
                    midPoint = line.get_centroid() 
                    midLatLon = pygplates.convert_point_on_sphere_to_lat_lon_point(midPoint)
                    midPointLatLon =  numpy.array([midLatLon.get_longitude(), midLatLon.get_latitude()])
                    
                    #Find the bearing of point 1 to point 2 (ALL IN RADIANS)
                    #eqns from http://www.movable-type.co.uk/scripts/latlong.html
                    radLat1 = numpy.radians(latPoint1)
                    radLat2 = numpy.radians(latPoint2)
                    radLon1 = numpy.radians(lonPoint1)
                    radLon2 = numpy.radians(lonPoint2)
                            
                    #θ = atan2( sin(Δλ).cos(φ2), cos(φ1).sin(φ2) − sin(φ1).cos(φ2).cos(Δλ) )
                    bearingRad = numpy.arctan2( numpy.sin(radLon2-radLon1) * numpy.cos(radLat2),\
                        numpy.cos(radLat1)*numpy.sin(radLat2) - numpy.sin(radLat1)*numpy.cos(radLat2)*numpy.cos(radLon2-radLon1))
                    #Now we march inside the polygon, to check if it is OP or SP
                    #Turn 90 degrees to the left or right
                    #if isright:
                    bearingPerp = bearingRad + 1.57
                    #else:
                    #    bearingPerp = bearingRad - 1.57
                    
                    #March into the plate a few km along the bearing.
                    #new Lat Lon are given below
                    d = 20.0 #km #Arbitrary small distance...
                    R=6371.0 #km Radius of Earth km
                    
                    #φ2 = asin( sin(φ1)*cos(d/R) + cos(φ1)*sin(d/R)*cos(θ) )
                    lat2 = numpy.arcsin(numpy.sin(radLat1)*numpy.cos(d/R) + numpy.cos(radLat1)*numpy.sin(d/R)*numpy.cos(bearingPerp))
                    #λ2 = λ1 + atan2( sin(θ)*sin(d/R)*cos(φ1), cos(d/R)−sin(φ1)*sin(φ2) )
                    lon2 = radLon1 + numpy.arctan2(numpy.sin(bearingPerp)*numpy.sin(d/R)*numpy.cos(radLat1),numpy.cos(d/R)-numpy.sin(radLat1)*numpy.sin(radLat2))        
                    pointSurface = pygplates.LatLonPoint(numpy.degrees(lat2),numpy.degrees(lon2))
                    pointSurfaceXYZ = pygplates.convert_lat_lon_point_to_point_on_sphere(pointSurface)
                    
                    #Test whether it is in the polygon or not
                    cwcheck = polygon.is_point_in_polygon(pointSurfaceXYZ)

                    #If it is then we have marched into the cojugate plate (probably)!
                    if cwcheck:
                        OPid=PLATEid
                        OPcount+=1
                    else:
                        SPid=PLATEid
                        SPcount+=1
                        
                #If the point does not exist on the polygon, pass                    
                else:
                    pass
                
            #After looping through the polygons, we should have one OPid, 
            #and one SPid, but these may be wrong for triple junctions.            
            if (OPcount == 1) and (SPcount == 1):
                #Now exit the Polygon loop and save the information about the point and move on 
                #print point[0],point[1], SPid, TRENCHid, OPid
                FinalArray.append([point[0],point[1], SPid, TRENCHid, OPid])
            else:
                pass
                #print OPcount, SPcount
                #print "Warning, point: ", point, TRENCHid, " found no match in polygons."
                #print "'BoundaryPoints' will not match actual points!"
    #print FinalArray            
    return(FinalArray)
Ejemplo n.º 10
0
def reconstruct_feature_collection(request):

    if request.method == 'POST':
        params = request.POST
    elif request.method == 'GET':
        params = request.GET
    else:
        return HttpResponseBadRequest('Unrecognized request type')

    anchor_plate_id = params.get('pid', 0)

    if 'time' in params:
        time = params['time']
    elif 'geologicage' in params:
        time = params['geologicage']
    else:
        time = 140 #default reconstruction age

    output_format = params.get('output', 'geojson')
    fc_str = params.get('feature_collection')
    model = str(params.get('model',settings.MODEL_DEFAULT))
    
    if 'keep_properties' in params:
        keep_properties = True
    else:
        keep_properties = False

    try:
        timef = float(time)
    except:
        return HttpResponseBadRequest('The "time" parameter is invalid ({0}).'.format(time))

    try:
        anchor_plate_id = int(anchor_plate_id)
    except:
        return HttpResponseBadRequest('The "pid" parameter is invalid ({0}).'.format(anchor_plate_id))
 
    # Convert geojson input to gplates feature collection
    features=[]
    try:
        fc = json.loads(fc_str)#load the input feature collection
        for f in fc['features']:
            geom = f['geometry']
            feature = pygplates.Feature()
            if geom['type'] == 'Point':
                feature.set_geometry(pygplates.PointOnSphere(
                    float(geom['coordinates'][1]),
                    float(geom['coordinates'][0])))
            if geom['type'] == 'LineString':
                feature.set_geometry(
                    pygplates.PolylineOnSphere([(point[1],point[0]) for point in geom['coordinates']]))
            if geom['type'] == 'Polygon':
                feature.set_geometry(
                    pygplates.PolygonOnSphere([(point[1],point[0]) for point in geom['coordinates'][0]]))
            if geom['type'] == 'MultiPoint':
                 feature.set_geometry(
                    pygplates.MultiPointOnSphere([(point[1],point[0]) for point in geom['coordinates']]))
            
            if keep_properties and 'properties' in f:
                for pk in f['properties']:           
                    p = f['properties'][pk] 
                    if isinstance(p, str):
                        p=str(p) 
                    feature.set_shapefile_attribute(str(pk),p)
            
            features.append(feature)
    except Exception as e:
        #print e
        return HttpResponseBadRequest('Invalid input feature collection')

    model_dict = get_reconstruction_model_dict(model)
    if not model_dict:
        return HttpResponseBadRequest('The "model" ({0}) cannot be recognized.'.format(model))

    rotation_model = pygplates.RotationModel([str('%s/%s/%s' %
        (settings.MODEL_STORE_DIR,model,rot_file)) for rot_file in model_dict['RotationFile']])

    assigned_features = pygplates.partition_into_plates(
        settings.MODEL_STORE_DIR+model+'/'+model_dict['StaticPolygons'],
        rotation_model,
        features,
        properties_to_copy = [
            pygplates.PartitionProperty.reconstruction_plate_id,
            pygplates.PartitionProperty.valid_time_period],
        partition_method = pygplates.PartitionMethod.most_overlapping_plate
    )

    reconstructed_geometries = []
    pygplates.reconstruct(assigned_features, 
        rotation_model, 
        reconstructed_geometries, 
        timef, 
        anchor_plate_id=anchor_plate_id)

    # convert feature collection back to geojson
    data = {"type": "FeatureCollection"}
    data["features"] = []
    for g in reconstructed_geometries:
        geom =  g.get_reconstructed_geometry()
        feature = {"type": "Feature"}
        feature["geometry"] = {}
        if isinstance(geom, pygplates.PointOnSphere):
            feature["geometry"]["type"] = "Point"
            p = geom.to_lat_lon_list()[0]
            feature["geometry"]["coordinates"] = [p[1], p[0]]
        elif isinstance(geom, pygplates.MultiPointOnSphere):
            feature["geometry"]["type"] = 'MultiPoint'
            feature["geometry"]["coordinates"] = [[lon,lat] for lat, lon in geom.to_lat_lon_list()]
        elif isinstance(geom, pygplates.PolylineOnSphere):
            feature["geometry"]["type"] = 'LineString'
            feature["geometry"]["coordinates"] = [[lon,lat] for lat, lon in geom.to_lat_lon_list()]
        elif isinstance(geom, pygplates.PolygonOnSphere):
            feature["geometry"]["type"] = 'Polygon'
            feature["geometry"]["coordinates"] = [[[lon,lat] for lat, lon in geom.to_lat_lon_list()]]
        else:
            return HttpResponseServerError('Unsupported Geometry Type.')

        feature["properties"] = {}
        if keep_properties:
            for pk in g.get_feature().get_shapefile_attributes():
                feature["properties"][pk] = g.get_feature().get_shapefile_attribute(pk)
        #print feature["properties"]
        data["features"].append(feature)

    ret = json.dumps(pretty_floats(data))
    
    #add header for CORS
    #http://www.html5rocks.com/en/tutorials/cors/
    response = HttpResponse(ret, content_type='application/json')
    #TODO:
    response['Access-Control-Allow-Origin'] = '*'
    return response
Ejemplo n.º 11
0
def plot_groups(equal_area_points, bin_values, fig=None, filename=None, grid_resolution=0.2,
                color_range=None, cmap='hot', reverse=True, pen='0.1p,gray50', transparency=0, **kwargs):

    """
    Generate a visual representation of spatially binned data generated by 'groupby_healpix'.
    The result can either be added to a pygmt figure or saved to a GIS file (with the file
    type taken from the filename extension of the optional 'filename' parameter, e.g. shp, gmt, geojson) 
    """

    points = pygplates.MultiPointOnSphere(zip(equal_area_points.latitude,equal_area_points.longitude)).to_xyz_array() 

    radius = 1
    center = np.array([0, 0, 0])
    sv = spatial.SphericalVoronoi(points, radius, center)
    sv.sort_vertices_of_regions()

    polygon_features = []
    for region,zval in zip(sv.regions,bin_values):
        polygon = np.vstack((sv.vertices[region],sv.vertices[region][0,:]))
        polygon_feature = pygplates.Feature()
        polygon_feature.set_geometry(pygplates.PolygonOnSphere(polygon))
        polygon_feature.set_shapefile_attribute('zval', zval)
        polygon_features.append(polygon_feature)

    if filename:
        return_file = True
        pygplates.FeatureCollection(polygon_features).write(filename)

    else:
        return_file = False
        plot_file = tempfile.NamedTemporaryFile(delete=False, suffix='.gmt')
        plot_file.close()
        filename = plot_file.name
        pygplates.FeatureCollection(polygon_features).write(filename)

    if fig:
        grid_lon, grid_lat = np.meshgrid(np.arange(-180.,180.,grid_resolution),np.arange(-90.,90.,grid_resolution))
    
        d,l = sampleOnSphere(np.radians(equal_area_points.longitude),
                            np.radians(equal_area_points.latitude),
                            np.array(bin_values),
                            np.radians(grid_lon).ravel(),
                            np.radians(grid_lat).ravel(),
                            k=1)
        grid_z = np.array(bin_values)[l].reshape(grid_lon.shape)
        
        #spherical_triangulation = stripy.sTriangulation(lons=np.radians(equal_area_points.longitude), lats=np.radians(equal_area_points.latitude))
        #grid_z,_ = spherical_triangulation.interpolate_nearest(np.radians(grid_lon).ravel(), np.radians(grid_lat).ravel(), np.array(bin_values))

        ds = xr.DataArray(grid_z.reshape(grid_lon.shape), coords=[('lat',grid_lat[:,0]), ('lon',grid_lon[0,:])], name='z')

        #pygmt.config(COLOR_FOREGROUND='white', COLOR_BACKGROUND='black')
        if not color_range:
            color_range = (np.nanmin(bin_values), np.nanmax(bin_values))
            reverse = True
        pygmt.makecpt(cmap=cmap, series='{:f}/{:f}'.format(color_range[0],color_range[1]), 
                      reverse=reverse, background='o')

        # This line would allow the polygons to be plotted directly with a colormap, but tends to crash when 
        # healpix of N=32 or greater is input
        #fig.plot(data=filename, pen=pen, color='+z', cmap=True, a='Z=zval', close=True, **kwargs)
        fig.grdimage(ds, transparency=transparency, cmap=True, nan_transparent=True)
        fig.plot(data=filename, pen=pen, transparency=transparency, close=True, **kwargs)


    if not return_file:
        os.unlink(plot_file.name)
Ejemplo n.º 12
0
def get_coastline_polygons(request):
    #pr = cProfile.Profile()
    #pr.enable()
    
    time = request.GET.get('time', 0)
    features = []
    ''' 
    polygons = CoastlinePolygons.objects.all()
    #polygons = StaticPolygons.objects.all()

    for p in polygons:
        polygon_feature = pygplates.Feature()
        polygon_feature.set_geometry(
            pygplates.PolygonOnSphere([(lat,lon) for lon, lat in p.geom[0][0]]))
        polygon_feature.set_reconstruction_plate_id(int(p.plateid1))
        features.append(polygon_feature)
    '''
    import shapefile 
    sf = shapefile.Reader(
        MODEL_DEFAULT+"coastlines_low_res/Seton_etal_ESR2012_Coastlines_2012.shp") 
    for record in sf.shapeRecords():
        if record.shape.shapeType != 5:
            continue
        for idx in range(len(record.shape.parts)):
            start_idx = record.shape.parts[idx]
            end_idx = len(record.shape.points)
            if idx < (len(record.shape.parts) -1):
                end_idx = record.shape.parts[idx+1]
            polygon_feature = pygplates.Feature()
            points = record.shape.points[start_idx:end_idx]
            polygon_feature.set_geometry(
                pygplates.PolygonOnSphere([(lat,lon) for lon, lat in points]))
            polygon_feature.set_reconstruction_plate_id(int(record.record[0]))
            features.append(polygon_feature)
            break 
     
    feature_collection = pygplates.FeatureCollection(features)
    reconstructed_polygons = []
    rotation_model = pygplates.RotationModel(
        MODEL_DEFAULT+"Seton_etal_ESR2012_2012.1.rot")    

    '''
    pr.disable()
    s = StringIO.StringIO()
    sortby = 'cumulative'
    ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
    ps.print_stats(20)
    print s.getvalue()
    '''
    
    pygplates.reconstruct(
        feature_collection, 
        rotation_model, 
        reconstructed_polygons,
        float(time))
    
    #return HttpResponse('OK')
    data = {"type": "FeatureCollection"}
    data["features"] = [] 
    for p in reconstructed_polygons:
        feature = {"type": "Feature"}
        feature["geometry"] = {}
        feature["geometry"]["type"] = "Polygon"
        feature["geometry"]["coordinates"] = [[(lon,lat) for lat, lon in p.get_reconstructed_geometry().to_lat_lon_list()]]
        data["features"].append(feature)
    ret = json.dumps(pretty_floats(data))
   
    return HttpResponse(ret, content_type='application/json')
Ejemplo n.º 13
0
def reconstruct_feature_collection(request):
    DATA_DIR = Model_Root+'caltech/'

    if request.method == 'POST':
        return HttpResponse('POST method is not accepted for now.')

    geologicage = request.GET.get('geologicage', 140)
    output_format = request.GET.get('output', 'geojson')
    fc_str = request.GET.get('feature_collection')
    fc = json.loads(fc_str)
 
    features=[]
    for f in fc['features']:
        geom = f['geometry']
        feature = pygplates.Feature()
        if geom['type'] == 'Point':
            feature.set_geometry(pygplates.PointOnSphere(
                float(geom['coordinates'][1]),
                float(geom['coordinates'][0])))
        if geom['type'] == 'LineString':
            feature.set_geometry(
                pygplates.PolylineOnSphere([(point[1],point[0]) for point in geom['coordinates']]))
        if geom['type'] == 'Polygon':
            feature.set_geometry(
                pygplates.PolygonOnSphere([(point[1],point[0]) for point in geom['coordinates'][0]]))
        if geom['type'] == 'MultiPoint':
             feature.set_geometry(
                pygplates.MultiPointOnSphere([(point[1],point[0]) for point in geom['coordinates']]))

        features.append(feature)


    if float(geologicage) < 250:
        rotation_files = [DATA_DIR+'/Seton_etal_ESR2012_2012.1.rot']
    else :
        rotation_files = [DATA_DIR+'/Global_EB_410-250Ma_GK07_Matthews_etal.rot']

    rotation_model = pygplates.RotationModel(rotation_files)

    assigned_features = pygplates.partition_into_plates(
        DATA_DIR+'Seton_etal_ESR2012_StaticPolygons_2012.1.gpmlz',
        rotation_model,
        features,
        properties_to_copy = [
            pygplates.PartitionProperty.reconstruction_plate_id,
            pygplates.PartitionProperty.valid_time_period],
        partition_method = pygplates.PartitionMethod.most_overlapping_plate
    )


    reconstructed_geometries = []
    pygplates.reconstruct(assigned_features, rotation_model, reconstructed_geometries, float(geologicage), 0)
    
    
    data = {"type": "FeatureCollection"}
    data["features"] = []
    for g in reconstructed_geometries:
        geom =  g.get_reconstructed_geometry()
        feature = {"type": "Feature"}
        feature["geometry"] = {}
        if isinstance(geom, pygplates.PointOnSphere):
            feature["geometry"]["type"] = "Point"
            p = geom.to_lat_lon_list()[0]
            feature["geometry"]["coordinates"] = [p[1], p[0]]
        elif isinstance(geom, pygplates.MultiPointOnSphere):
            feature["geometry"]["type"] = 'MultiPoint'
            feature["geometry"]["coordinates"] = [[lon,lat] for lat, lon in geom.to_lat_lon_list()]
        elif isinstance(geom, pygplates.PolylineOnSphere):
            feature["geometry"]["type"] = 'LineString'
            feature["geometry"]["coordinates"] = [[lon,lat] for lat, lon in geom.to_lat_lon_list()]
        elif isinstance(geom, pygplates.PolygonOnSphere):
            feature["geometry"]["type"] = 'Polygon'
            feature["geometry"]["coordinates"] = [[[lon,lat] for lat, lon in geom.to_lat_lon_list()]]
        else:
            raise 'Unrecognized Geometry Type.'
        
        feature["properties"]={}    
        
        data["features"].append(feature)

    ret = json.dumps(pretty_floats(data))

    return HttpResponse(ret, content_type='application/json')
Ejemplo n.º 14
0
def wrap_resolved_polygons(resolved_polygons,
                           wrap=False,
                           central_meridian=0,
                           avoid_map_boundary=False,
                           tesselate_degrees=2):

    polygons = []
    if wrap:
        wrapped_polygons = []
        date_line_wrapper = pygplates.DateLineWrapper(central_meridian)
        for p in resolved_polygons:
            wrapped_polygons += date_line_wrapper.wrap(p.get_geometry(),
                                                       tesselate_degrees)
        for p in wrapped_polygons:
            lats = [i.get_latitude() for i in p.get_exterior_points()]
            lons = [i.get_longitude() for i in p.get_exterior_points()]
            if pygplates.PolygonOnSphere(list(zip(
                    lats, lons))).get_orientation(
                    ) == pygplates.PolygonOnSphere.Orientation.clockwise:
                polygons.append((lons, lats))
            else:
                polygons.append((lons[::-1], lats[::-1]))
    else:
        for p in resolved_polygons:
            lats, lons = list(zip(*p.get_geometry().to_lat_lon_list()))
            lats = list(lats)
            lons = list(lons)
            if pygplates.PolygonOnSphere(list(zip(
                    lats, lons))).get_orientation(
                    ) == pygplates.PolygonOnSphere.Orientation.clockwise:
                polygons.append((lons, lats))
            else:
                polygons.append((lons[::-1], lats[::-1]))

    data = {"type": "FeatureCollection"}
    data["features"] = []
    for p in polygons:
        feature = {"type": "Feature"}
        feature["geometry"] = {}
        feature["geometry"]["type"] = "Polygon"

        #make sure the coordinates are valid.
        lats = p[1]
        lons = p[0]
        #print lats, lons
        #some map plotting program(such as leaflet) does not like points on the map boundary,
        #for example the longitude 180 and -180.
        #So, move the points slightly inwards.
        if avoid_map_boundary:
            for idx, x in enumerate(lons):
                if x < central_meridian - 179.99:
                    lons[idx] = central_meridian - 179.99
                elif x > central_meridian + 179.99:
                    lons[idx] = central_meridian + 179.99
            for idx, x in enumerate(lats):
                if x < -89.99:
                    lats[idx] = -89.99
                elif x > 89.99:
                    lats[idx] = 89.99

        feature["geometry"]["coordinates"] = [
            list(zip(lons + lons[:1], lats + lats[:1]))
        ]
        data["features"].append(feature)

    return data