Ejemplo n.º 1
0
    def xu_ly_duong_bo_nuoc(self):
        arcpy.env.overwriteOutput = 1
        # Khai bao bien
        SongSuoiA = self.duong_dan_nguon + "ThuyHe/SongSuoiA"
        MatNuocTinh = self.duong_dan_nguon + "ThuyHe/MatNuocTinh"
        KenhMuongA = self.duong_dan_nguon + "ThuyHe/KenhMuongA"
        lop_bai_boi = self.duong_dan_nguon + "ThuyHe/BaiBoiA"
        SongSuoiA_Copy = SongSuoiA + "_Copy"
        MatNuocTinh_Copy = MatNuocTinh + "_Copy"
        KenhMuongA_Copy = KenhMuongA + "_Copy"
        lop_thuy_he_Copy_Agg = SongSuoiA_Copy + "_Agg"
        lop_thuy_he_Copy_Agg_Tbl = self.duong_dan_nguon + "SongSuoiA_Copy_Agg_Tbl"

        lop_thuy_he_DuongBoNuoc = SongSuoiA_Copy + "_DuongBoNuoc"

        arcpy.Snap_edit(lop_bai_boi, [[KenhMuongA, "EDGE", self.khoang_Cach],
                                      [MatNuocTinh, "EDGE", self.khoang_Cach],
                                      [SongSuoiA, "EDGE", self.khoang_Cach]])
        #Append
        arcpy.CopyFeatures_management(SongSuoiA, SongSuoiA_Copy)
        arcpy.AddField_management(SongSuoiA_Copy, "LOAI_RANH_GIOI", "LONG",
                                  None, None, None, "LOAI_RANH_GIOI",
                                  "NULLABLE")
        arcpy.CalculateField_management(SongSuoiA_Copy, "LOAI_RANH_GIOI", 6,
                                        "PYTHON_9.3")
        arcpy.CopyFeatures_management(MatNuocTinh, MatNuocTinh_Copy)
        arcpy.AddField_management(MatNuocTinh_Copy, "LOAI_RANH_GIOI", "LONG",
                                  None, None, None, "LOAI_RANH_GIOI",
                                  "NULLABLE")
        arcpy.CalculateField_management(MatNuocTinh_Copy, "LOAI_RANH_GIOI", 1,
                                        "PYTHON_9.3")
        arcpy.CopyFeatures_management(KenhMuongA, KenhMuongA_Copy)
        arcpy.AddField_management(KenhMuongA_Copy, "LOAI_RANH_GIOI", "LONG",
                                  None, None, None, "LOAI_RANH_GIOI",
                                  "NULLABLE")
        arcpy.CalculateField_management(KenhMuongA_Copy, "LOAI_RANH_GIOI", 4,
                                        "PYTHON_9.3")
        arcpy.Append_management(
            [lop_bai_boi, MatNuocTinh_Copy, KenhMuongA_Copy], SongSuoiA_Copy,
            "NO_TEST", None, None)
        #AggregatePolygons
        arcpy.AggregatePolygons_cartography(SongSuoiA_Copy,
                                            lop_thuy_he_Copy_Agg,
                                            "0.001 Meters", "0 SquareMeters",
                                            "0 SquareMeters", "NON_ORTHOGONAL",
                                            "", lop_thuy_he_Copy_Agg_Tbl)

        DM.JoinField(lop_thuy_he_Copy_Agg_Tbl, "INPUT_FID", SongSuoiA_Copy,
                     "OBJECTID", None)
        #danh dau sông có diện tích lớn nhất trong group
        rows2 = arcpy.SearchCursor(lop_thuy_he_Copy_Agg_Tbl,
                                   sort_fields="OUTPUT_FID A")
        _outPut_id = 0
        _area_max = 0
        my_dict = {}
        for row2 in rows2:
            if row2.getValue("LOAI_RANH_GIOI") is not None:
                if _outPut_id == row2.getValue("OUTPUT_FID"):
                    if _area_max < row2.getValue("Shape_Area"):
                        _area_max = row2.getValue("Shape_Area")
                        my_dict[row2.getValue("OUTPUT_FID")] = _area_max
                else:
                    _area_max = row2.getValue("Shape_Area")
                    my_dict[row2.getValue("OUTPUT_FID")] = _area_max
                _outPut_id = row2.getValue("OUTPUT_FID")
        #Update lại bảng join
        rows_update = arcpy.UpdateCursor(lop_thuy_he_Copy_Agg_Tbl)
        for row_update in rows_update:
            if row_update.getValue("LOAI_RANH_GIOI") is None:
                rows_update.deleteRow(row_update)
            else:
                if row_update.getValue("Shape_Area") != my_dict[
                        row_update.getValue("OUTPUT_FID")]:
                    rows_update.deleteRow(row_update)
        del row_update
        del rows_update
        DM.JoinField(lop_thuy_he_Copy_Agg, "OBJECTID",
                     lop_thuy_he_Copy_Agg_Tbl, "OUTPUT_FID", None)
        #Xóa bãi bồi trong Aggregate
        rows_update = arcpy.UpdateCursor(lop_thuy_he_Copy_Agg)
        for row_update in rows_update:
            if row_update.getValue("LOAI_RANH_GIOI") is None:
                rows_update.deleteRow(row_update)
        del row_update
        del rows_update
        #FeatureToLine
        arcpy.FeatureToLine_management([lop_thuy_he_Copy_Agg],
                                       lop_thuy_he_DuongBoNuoc, None,
                                       "ATTRIBUTES")
        #Chỉnh sửa lại field
        arcpy.DeleteField_management(lop_thuy_he_DuongBoNuoc, [
            "FID_SongSuoiA_Copy2_Agg", "OUTPUT_FID", "INPUT_FID",
            "loaiTrangThaiNuocMat", "ten", "doRong", "SongSuoiA_Rep_ID",
            "SongSuoiA_Rep_OVERRIDE", "RuleID", "Override", "Shape_Length_1",
            "Shape_Area_1", "loaiTrangThaiDuongBoNuoc", "loaiRanhGioiNuocMat"
        ])
        arcpy.AddField_management(lop_thuy_he_DuongBoNuoc,
                                  "loaiTrangThaiDuongBoNuoc", "SHORT", None,
                                  None, None, "Loai trang thai duong bo nuoc",
                                  "NULLABLE", None, "LoaiTrangThaiDuongBoNuoc")
        arcpy.AddField_management(lop_thuy_he_DuongBoNuoc,
                                  "loaiRanhGioiNuocMat", "LONG", None, None,
                                  None, "Loai ranh gioi nuoc mat", "NULLABLE",
                                  None, "LoaiRanhGioiNuocMat")
        arcpy.CalculateField_management(lop_thuy_he_DuongBoNuoc,
                                        "loaiTrangThaiDuongBoNuoc", 1,
                                        "PYTHON_9.3")
        arcpy.CalculateField_management(lop_thuy_he_DuongBoNuoc,
                                        "loaiRanhGioiNuocMat",
                                        "!LOAI_RANH_GIOI!", "PYTHON_9.3")
        arcpy.AssignDefaultToField_management(lop_thuy_he_DuongBoNuoc,
                                              "maDoiTuong", "LG01", None)
        arcpy.CalculateField_management(lop_thuy_he_DuongBoNuoc, "maDoiTuong",
                                        "'LG01'", "PYTHON_9.3")
        arcpy.DeleteField_management(lop_thuy_he_DuongBoNuoc,
                                     ["LOAI_RANH_GIOI"])

        DuongBoNuoc_Path = self.duong_dan_nguon + "ThuyHe/DuongBoNuoc"
        if int(arcpy.GetCount_management(DuongBoNuoc_Path).getOutput(0)) > 0:
            arcpy.DeleteFeatures_management(DuongBoNuoc_Path)

        duongBoNuocFields = [
            "SHAPE@", "maNhanDang", "ngayThuNhan", "ngayCapNhat", "maDoiTuong",
            "loaiTrangThaiDuongBoNuoc", "loaiRanhGioiNuocMat", "nguonDuLieu",
            "maTrinhBay", "tenManh", "soPhienHieuManhBanDo"
        ]
        duongBoNuocFields2 = [
            "SHAPE@", "maNhanDang", "ngayThuNhan", "ngayCapNhat", "maDoiTuong",
            "loaiTrangThaiDuongBoNuoc", "loaiRanhGioiNuocMat", "nguonDuLieu",
            "maTrinhBay", "tenManh", "soPhienHieuManhBanDo",
            "DuongBoNuoc_Rep_ID"
        ]
        with arcpy.da.SearchCursor(lop_thuy_he_DuongBoNuoc,
                                   duongBoNuocFields) as sCur:
            with arcpy.da.InsertCursor(DuongBoNuoc_Path,
                                       duongBoNuocFields2) as iCur:
                for sRow in sCur:
                    iCur.insertRow([
                        sRow[0], sRow[1], sRow[2], sRow[3], sRow[4], sRow[5],
                        sRow[6], sRow[7], sRow[8], sRow[9], sRow[10], 1
                    ])
        arcpy.CopyFeatures_management(
            DuongBoNuoc_Path, self.duong_dan_dich + "ThuyHe/DuongBoNuoc")
Ejemplo n.º 2
0
def georeference_lakes(
    lake_points_fc,
    out_fc,
    lake_id_field,
    lake_name_field,
    lake_county_field='',
    state='',
    master_gdb=r'C:\Users\smithn78\Dropbox\CL_HUB_GEO\Lake_Georeferencing\Masters_for_georef.gdb'
):
    """
    Evaluate water quality sampling point locations and either assign the point to a lake polygon or flag the
    point for manual review.
    :param lake_points_fc:
    :param out_fc:
    :param lake_id_field:
    :param lake_name_field:
    :param lake_county_field:
    :param state:
    :param master_gdb: Location of master geodatabase used for linking
    :return:
    """
    master_lakes_fc = os.path.join(master_gdb, MASTER_LAKES_FC)
    master_lakes_lines = os.path.join(master_gdb, MASTER_LAKES_LINES)
    master_streams_fc = os.path.join(master_gdb, MASTER_STREAMS_FC)
    master_xwalk = os.path.join(master_gdb, MASTER_XWALK)

    # setup
    arcpy.AddMessage("Joining...")
    state = state.upper()
    if state not in STATES:
        raise ValueError('Use the 2-letter state code abbreviation')
    arcpy.env.workspace = 'in_memory'
    out_short = os.path.splitext(os.path.basename(out_fc))[0]
    join1 = '{}_1'.format(out_short)
    join2 = '{}_2'.format(out_short)
    join3 = '{}_3'.format(out_short)
    join3_select = join3 + '_select'
    join4 = '{}_4'.format(out_short)
    join5 = '{}_5'.format(out_short)
    joinx = '{}_x'.format(out_short)

    county_name_results = arcpy.ListFields(
        lake_points_fc, '{}*'.format(lake_county_field))[0].name
    if lake_county_field and not lake_county_field in county_name_results:
        print('{} field does not exist in dataset.'.format(lake_county_field))
        raise Exception

    point_fields = [f.name for f in arcpy.ListFields(lake_points_fc)]

    # update the lake id to a text field if not already
    lake_id_field_type = arcpy.ListFields(lake_points_fc,
                                          lake_id_field)[0].type
    if lake_id_field_type != 'String':
        temp_id_field = '{}_t'.format(lake_id_field)
        arcpy.AddField_management(lake_points_fc, '{}_t'.format(lake_id_field),
                                  'TEXT', '255')
        expr = '!{}!'.format(lake_id_field)
        arcpy.CalculateField_management(lake_points_fc, temp_id_field, expr,
                                        'PYTHON')
        arcpy.DeleteField_management(lake_points_fc, lake_id_field)
        arcpy.AlterField_management(lake_points_fc,
                                    temp_id_field,
                                    new_field_name=lake_id_field)

    # Try to make some spatial connections and fulfill some logic to assign a link
    join1 = AN.SpatialJoin(lake_points_fc,
                           master_lakes_fc,
                           join1,
                           'JOIN_ONE_TO_MANY',
                           'KEEP_ALL',
                           match_option='INTERSECT')
    join2 = AN.SpatialJoin(join1,
                           master_streams_fc,
                           join2,
                           'JOIN_ONE_TO_MANY',
                           'KEEP_ALL',
                           match_option='INTERSECT')
    join3 = AN.SpatialJoin(join2,
                           master_lakes_fc,
                           join3,
                           'JOIN_ONE_TO_MANY',
                           'KEEP_ALL',
                           match_option='INTERSECT',
                           search_radius='10 meters')
    join4 = AN.SpatialJoin(join3,
                           master_lakes_fc,
                           join4,
                           'JOIN_ONE_TO_MANY',
                           'KEEP_ALL',
                           match_option='INTERSECT',
                           search_radius='100 meters')

    # setup for editing lake assignment values
    DM.AddField(join4, 'Auto_Comment', 'TEXT', field_length=100)
    DM.AddField(join4, 'Manual_Review', 'SHORT')
    DM.AddField(join4, 'Shared_Words', 'TEXT', field_length=100)
    DM.AddField(join4, 'Linked_lagoslakeid', 'LONG')
    DM.AddField(join4, 'GEO_Discovered_Name', 'TEXT', field_length=255)
    DM.AddField(join4, 'Duplicate_Candidate', 'TEXT', field_length=1)
    DM.AddField(join4, 'Is_Legacy_Link', 'TEXT', field_length=1)

    update_fields = [
        lake_id_field,
        lake_name_field,
        MASTER_LAKE_ID,
        MASTER_GNIS_NAME,  # 0m match
        'PERMANENT_IDENTIFIER_1',
        'GNIS_NAME_1',  # stream match
        MASTER_LAKE_ID + '_1',
        MASTER_GNIS_NAME + '_12',  # 10m match
        MASTER_LAKE_ID + '_12',
        MASTER_GNIS_NAME + '_12_13',  # 100m match
        'Auto_Comment',
        'Manual_Review',
        'Shared_Words',
        'Linked_lagoslakeid'
    ]

    # use a cursor to go through each point and evaluate its assignment
    cursor = arcpy.da.UpdateCursor(join4, update_fields)
    arcpy.AddMessage("Calculating link status...")
    for row in cursor:
        id, name, mid_0, mname_0, stream_id, streamname_0, mid_10, mname_10, mid_100, mname_100, comment, review, words, lagosid = row
        if mid_0 is not None:  # if the point is directly in a polygon
            if name and mname_0:
                words = lagosGIS.list_shared_words(name,
                                                   mname_0,
                                                   exclude_lake_words=False)
            comment = 'Exact location link'
            lagosid = mid_0
            review = -1
        elif mid_0 is None and mid_10 is not None:  # if the point is only within 10m of a lake
            if name and mname_10:
                words = lagosGIS.list_shared_words(name,
                                                   mname_10,
                                                   exclude_lake_words=False)
            if words:
                comment = 'Linked by common name and location'
                lagosid = mid_10
                review = -1
            else:
                comment = 'Linked by common location'
                lagosid = mid_10
                review = 1
        elif mid_0 is None and mid_10 is None:
            if stream_id is not None:  # if there is a stream match
                comment = 'Not linked because represented as river in NHD'
                review = 2
            else:
                if mid_100 is not None:  # if the point is only within 100m of lake(s)
                    if name and mname_100:
                        words = lagosGIS.list_shared_words(
                            name, mname_100, exclude_lake_words=True)
                # TODO: Frequency check
                    if words:
                        comment = 'Linked by common name and location'
                        lagosid = mid_100
                        review = 1
                    else:
                        comment = 'Linked by common location'
                        lagosid = mid_100
                        review = 2
        cursor.updateRow(
            (id, name, mid_0, mname_0, stream_id, streamname_0, mid_10,
             mname_10, mid_100, mname_100, comment, review, words, lagosid))

    # # So I haven't been able to get the county logic to work and it hasn't been that important yet, ignore for now
    # Select down to a minimum set because we're about to join on county, which will create lots of duplicate matches
    # Then join calculated results back to full set
    # if lake_county_field:
    #     join5 = AN.Select(join4, join5, 'Manual_Review IS NULL')
    #     lakes_state = AN.Select(MASTER_LAKES_FC, 'lakes_state', "{0} = '{1}'".format(MASTER_STATE_NAME, state))
    #     lakes_state_lyr = DM.MakeFeatureLayer(lakes_state, 'lakes_state_lyr')
    #     join5_lyr = DM.MakeFeatureLayer(join5, 'join5_lyr')
    #     DM.AddJoin(join5_lyr, lake_county_field, lakes_state_lyr, MASTER_COUNTY_NAME)
    #     join5_with_county = DM.CopyFeatures(join5_lyr, 'join5_with_cty')
    #     j5 = 'DEDUPED_CA_SWAMP_data_linked_5.'
    #
    #     county_update_fields = [j5 + lake_id_field, j5 + lake_name_field, j5 + lake_county_field,
    #                             'lakes_state.' + MASTER_LAKE_ID, 'lakes_state.' + MASTER_GNIS_NAME, 'lakes_state.' + MASTER_COUNTY_NAME,
    #                             j5 + 'Auto_Comment', j5 + 'Manual_Review', j5 + 'Shared_Words',
    #                             j5 + 'Linked_lagoslakeid']
    #     with arcpy.da.UpdateCursor(join5_lyr, county_update_fields) as cursor:
    #         for row in cursor:
    #             id, name, county, mid_cty, mname_cty, mcounty, comment, review, words, lagosid = row
    #             if county is not None and mcounty is not None:
    #                 if name and mname_cty:
    #                     words = lagosGIS.list_shared_words(name, mname_cty, exclude_lake_words=True)
    #                 if words:
    #                     comment = 'PRELIMINARY: Linked by common name and location'
    #                     lagosid = mid_cty
    #                     review = 2
    #             cursor.updateRow((id, name, county, mid_cty, mname_cty, mcounty, comment, review, words, lagosid))
    #     DM.RemoveJoin(join5_lyr)
    #     join5_with_county = DM.CopyFeatures(join5_lyr, 'join5_with_county')
    #
    #     # join5 = DM.JoinField(join5, lake_county_field, lakes_state, MASTER_COUNTY_NAME,
    #                          fields = [MASTER_COUNTY_NAME, MASTER_LAKE_ID, MASTER_GNIS_NAME])
    #
    #     # This is a long way to make a join
    #     join_dict = {}
    #     with arcpy.da.SearchCursor(lakes_state, [MASTER_COUNTY_NAME, MASTER_LAKE_ID, MASTER_GNIS_NAME]) as cursor:
    #         for row in cursor:
    #             join_value, val1, val2 = row
    #             join_dict[join_value] = [val1, val2]
    #
    #     arcpy.AddField_management(join5, MASTER_LAKE_ID + 'cntyj', 'LONG')
    #     arcpy.AddField_management(join5, MASTER_GNIS_NAME + 'cntyj', 'TEXT', 255)
    #
    #     with arcpy.da.SearchCursor(join5, [lake_county_field, MASTER_LAKE_ID + 'cntyj', MASTER_GNIS_NAME + 'cntyj']) as cursor:
    #         for row in cursor:
    #             key_value = row[0]
    #             words = lagosGIS.list_shared_words()
    #             if join_dict.has_key(key_value):
    #                 row[1] = join_dict[key_value][0]
    #                 row[2] = join_dict[key_value][1]
    #             else:
    #                 row[1] = None
    #                 row[2] = None
    #             cursor.updateRow(row)
    #
    #
    #     county_update_fields = [lake_id_field, lake_name_field, lake_county_field,
    #                 MASTER_LAKE_ID + '_12_13_14', MASTER_GNIS_NAME + '_12_13',  MASTER_COUNTY_NAME + '_12_13', # county
    #                  'Auto_Comment', 'Manual_Review', 'Shared_Words',
    #                  'Linked_lagoslakeid']
    #     cursor = arcpy.da.UpdateCursor(join5, county_update_fields)
    #     for row in cursor:
    #         id, name, county, lagosid_cty, lagosname_cty, mcounty, comment, mreview, words, linked_lagosid = row
    #         if mcounty is not None:
    #             words = lagosGIS.list_shared_words()
    # else:
    #     join5 = join4
    #

    if state in LAGOSNE_STATES:
        DM.JoinField(join4, lake_id_field, master_xwalk, 'lagosne_legacyid',
                     ['lagoslakeid', 'lagos_lakename', 'lagos_state'])
        update_fields = [
            lake_id_field,
            lake_name_field,
            MASTER_LAKE_ID + '_12_13',
            'lagos_lakename',
            'lagos_state',  # crosswalk match
            'Auto_Comment',
            'Manual_Review',
            'Shared_Words',
            'Linked_lagoslakeid',
            'Is_Legacy_Link'
        ]

        with arcpy.da.UpdateCursor(join4, update_fields) as uCursor:
            for uRow in uCursor:
                id, name, mid_x, mname_x, state_x, comment, review, words, lagosid, legacy_flag = uRow
                # fields are populated already from links above. Revise only if legacy links
                if mid_x is not None:
                    if state == state_x:
                        legacy_flag = 'Y'  # set to Y regardless of whether using legacy comment if state matches
                    if comment != 'Exact location link':
                        review = 1
                        if state != state_x:
                            review = 3  # downgrade if states mismatch--border lakes OK, random common IDs NOT. Check.
                        legacy_flag = 'Y'
                        comment = 'LAGOS-NE legacy link'  # only comment non-exact location matches
                        lagosid = mid_x
                        if name and mname_x:
                            words = lagosGIS.list_shared_words(
                                name,
                                mname_x)  # update words only if legacy comment

                new_row = id, name, mid_x, mname_x, state_x, comment, review, words, lagosid, legacy_flag
                uCursor.updateRow(new_row)

        # # Undo the next line if you ever bring this chunk back.
    join5 = join4

    # then re-code the no matches as a 3 and copy comments to the editable field
    # compress the joined lake ids into one field
    # having two fields lets us keep track of how many of the auto matches are bad
    if arcpy.ListFields(join5, 'Comment'):
        comment_field_name = 'Comment_LAGOS'
    else:
        comment_field_name = 'Comment'

    DM.AddField(join5, comment_field_name, 'TEXT', field_length=100)
    with arcpy.da.UpdateCursor(
            join5, ['Manual_Review', 'Auto_Comment', 'Comment']) as cursor:
        for flag, ac, comment in cursor:
            if flag is None:
                flag = 3
                ac = 'Not linked'
            comment = ac
            cursor.updateRow((flag, ac, comment))

    # Re-code points more than 100m into the polygon of the lake as no need to check
    DM.MakeFeatureLayer(join5, 'join5_lyr')
    DM.MakeFeatureLayer(master_lakes_lines, 'lake_lines_lyr')
    DM.SelectLayerByAttribute('join5_lyr', 'NEW_SELECTION',
                              "Auto_Comment = 'Exact location link'")
    DM.SelectLayerByLocation('join5_lyr', 'INTERSECT', 'lake_lines_lyr',
                             '100 meters', 'SUBSET_SELECTION', 'INVERT')
    DM.CalculateField('join5_lyr', 'Manual_Review', '-2', 'PYTHON')
    DM.Delete('join5_lyr', 'lake_lines_lyr')

    # Then make sure to only keep the fields necessary when you write to an output
    copy_fields = point_fields + [
        'Linked_lagoslakeid', 'Auto_Comment', 'Manual_Review',
        'Is_Legacy_Link', 'Shared_Words', 'Comment', 'Duplicate_Candidate',
        'GEO_Discovered_Name'
    ]
    copy_fields.remove('Shape')
    copy_fields.remove('OBJECTID')

    lagosGIS.select_fields(join5, out_fc, copy_fields)

    DM.AssignDomainToField(out_fc, 'Comment', 'Comment')

    DM.AddField(out_fc, 'Total_points_in_lake_poly', 'Short')

    # Remove any duplicates. (These originate from the join3/join4 transition because a point can be both
    # within 10m and 100m of lakes, this code takes the closest lake as true for my current sanity.)
    # Or, in other words, this is a hack solution.
    out_fc_fields = [
        f.name for f in arcpy.ListFields(out_fc) if f.name != 'OBJECTID'
    ]
    DM.DeleteIdentical(out_fc, out_fc_fields)

    # Get the join_count for each limno lake ID
    # De-dupe anything resulting from limno ID duplicates first before counting
    id_pairs = list(
        set(
            arcpy.da.SearchCursor(out_fc,
                                  [lake_id_field, 'Linked_lagoslakeid'])))
    # THEN pull out LAGOS id. Any duplicate now are only due to multiple distinct points within lake
    lagos_ids = [ids[1] for ids in id_pairs]
    sample_ids = [ids[0] for ids in id_pairs]
    lagos_lake_counts = Counter(lagos_ids)
    linked_multiple_lake_counts = Counter(sample_ids)

    # Get the count of points in the polygon
    with arcpy.da.UpdateCursor(
            out_fc,
        ['Linked_lagoslakeid', 'Total_points_in_lake_poly']) as cursor:
        for lagos_id, join_count in cursor:
            join_count = lagos_lake_counts[lagos_id]
            cursor.updateRow((lagos_id, join_count))

    # Mark any samples linked to more than one lake so that the analyst can select the correct lake in the
    # manual process
    with arcpy.da.UpdateCursor(
            out_fc, [lake_id_field, 'Duplicate_Candidate']) as cursor:
        for sample_id, duplicate_flag in cursor:
            duplicate_count = linked_multiple_lake_counts[sample_id]
            if duplicate_count > 1:
                duplicate_flag = "Y"
            else:
                duplicate_flag = "N"
            cursor.updateRow((sample_id, duplicate_flag))

    # clean up
    DM.AddField(out_fc, 'Note', 'TEXT', field_length=140)
    DM.Delete('in_memory')
    arcpy.AddMessage('Completed.')
Ejemplo n.º 3
0
def process_zone(zone_fc, output, zone_name, zone_id_field, zone_name_field,
                 other_keep_fields, clip_hu8, lagosne_name):
    # dissolve fields by the field that zone_id is based on (the field that identifies a unique zone)
    dissolve_fields = [
        f for f in "{}, {}, {}".format(zone_id_field, zone_name_field,
                                       other_keep_fields).split(', ')
        if f != ''
    ]
    print("Dissolving...")
    dissolve1 = DM.Dissolve(zone_fc, 'dissolve1', dissolve_fields)

    # update name field to match our standard
    DM.AlterField(dissolve1, zone_name_field, 'name')

    # original area

    DM.AddField(dissolve1, 'originalarea', 'DOUBLE')
    DM.CalculateField(dissolve1, 'originalarea', '!shape.area@hectares!',
                      'PYTHON')

    #clip
    print("Clipping...")
    clip = AN.Clip(dissolve1, MASTER_CLIPPING_POLY, 'clip')
    if clip_hu8 == 'Y':
        final_clip = AN.Clip(clip, HU8_OUTPUT, 'final_clip')
    else:
        final_clip = clip

    print("Selecting...")
    # calc new area, orig area pct, compactness
    DM.AddField(final_clip, 'area_ha', 'DOUBLE')
    DM.AddField(final_clip, 'originalarea_pct', 'DOUBLE')
    DM.AddField(final_clip, 'compactness', 'DOUBLE')
    DM.JoinField(final_clip, zone_id_field, dissolve1, zone_id_field,
                 'originalarea_pct')

    uCursor_fields = [
        'area_ha', 'originalarea_pct', 'originalarea', 'compactness',
        'SHAPE@AREA', 'SHAPE@LENGTH'
    ]
    with arcpy.da.UpdateCursor(final_clip, uCursor_fields) as uCursor:
        for row in uCursor:
            area, orig_area_pct, orig_area, comp, shape_area, shape_length = row
            area = shape_area / 10000  # convert from m2 to hectares
            orig_area_pct = round(100 * area / orig_area, 2)
            comp = 4 * 3.14159 * shape_area / (shape_length**2)
            row = (area, orig_area_pct, orig_area, comp, shape_area,
                   shape_length)
            uCursor.updateRow(row)

    # if zones are present with <5% of original area and a compactness measure of <.2 (ranges from 0-1)
    # AND ALSO they are no bigger than 500 sq. km. (saves Chippewa County and a WWF), filter out
    # save eliminated polygons to temp database as a separate layer for inspection

    # Different processing for HU4 and HU8, so that they match the extent of HU8 more closely but still throw out tiny slivers
    # County also only eliminated if a tiny, tiny, tiny sliver (so: none should be eliminated)
    if zone_name not in ('hu4', 'hu12', 'county'):
        selected = AN.Select(
            final_clip, 'selected',
            "originalarea_pct >= 5 OR compactness >= .2 OR area_ha > 50000")
        not_selected = AN.Select(
            final_clip, '{}_not_selected'.format(output),
            "originalarea_pct < 5 AND compactness < .2 AND area_ha < 50000")

    else:
        selected = final_clip
    # eliminate small slivers, re-calc area fields, add perimeter and multipart flag
    # leaves the occasional errant sliver but some areas over 25 hectares are more valid so this is
    # CONSERVATIVE
    print("Trimming...")
    trimmed = DM.EliminatePolygonPart(selected,
                                      'trimmed',
                                      'AREA',
                                      '25 Hectares',
                                      part_option='ANY')

    # gather up a few calculations into one cursor because this is taking too long over the HU12 layer
    DM.AddField(trimmed, 'perimeter_m', 'DOUBLE')
    DM.AddField(trimmed, 'multipart', 'TEXT', field_length=1)
    uCursor_fields = [
        'area_ha', 'originalarea_pct', 'originalarea', 'perimeter_m',
        'multipart', 'SHAPE@'
    ]
    with arcpy.da.UpdateCursor(trimmed, uCursor_fields) as uCursor:
        for row in uCursor:
            area, orig_area_pct, orig_area, perim, multipart, shape = row
            area = shape.area / 10000  # convert to hectares from m2
            orig_area_pct = round(100 * area / orig_area, 2)
            perim = shape.length

            # multipart flag calc
            if shape.isMultipart:
                multipart = 'Y'
            else:
                multipart = 'N'
            row = (area, orig_area_pct, orig_area, perim, multipart, shape)
            uCursor.updateRow(row)

    # delete intermediate fields
    DM.DeleteField(trimmed, 'compactness')
    DM.DeleteField(trimmed, 'originalarea')

    print("Zone IDs....")
    # link to LAGOS-NE zone IDs
    DM.AddField(trimmed, 'zoneid', 'TEXT', field_length=40)
    trimmed_lyr = DM.MakeFeatureLayer(trimmed, 'trimmed_lyr')
    if lagosne_name:
        # join to the old master GDB path on the same master field and copy in the ids
        old_fc = os.path.join(LAGOSNE_GDB, lagosne_name)
        old_fc_lyr = DM.MakeFeatureLayer(old_fc, 'old_fc_lyr')
        if lagosne_name == 'STATE' or lagosne_name == 'COUNTY':
            DM.AddJoin(trimmed_lyr, zone_id_field, old_fc_lyr, 'FIPS')
        else:
            DM.AddJoin(trimmed_lyr, zone_id_field, old_fc_lyr,
                       zone_id_field)  # usually works because same source data

        # copy
        DM.CalculateField(trimmed_lyr, 'zoneid',
                          '!{}.ZoneID!.lower()'.format(lagosne_name), 'PYTHON')
        DM.RemoveJoin(trimmed_lyr)

    # generate new zone ids
    old_ids = [row[0] for row in arcpy.da.SearchCursor(trimmed, 'zoneid')]
    with arcpy.da.UpdateCursor(trimmed, 'zoneid') as cursor:
        counter = 1
        for row in cursor:
            if not row[
                    0]:  # if no existing ID borrowed from LAGOS-NE, assign a new one
                new_id = '{name}_{num}'.format(name=zone_name, num=counter)

                # ensures new ids don't re-use old numbers but fills in all positive numbers eventually
                while new_id in old_ids:
                    counter += 1
                    new_id = '{name}_{num}'.format(name=zone_name, num=counter)
                row[0] = new_id
                cursor.updateRow(row)
                counter += 1

    print("Edge flags...")
    # add flag fields
    DM.AddField(trimmed, 'onlandborder', 'TEXT', field_length=2)
    DM.AddField(trimmed, 'oncoast', 'TEXT', field_length=2)

    # identify border zones
    border_lyr = DM.MakeFeatureLayer(LAND_BORDER, 'border_lyr')
    DM.SelectLayerByLocation(trimmed_lyr, 'INTERSECT', border_lyr)
    DM.CalculateField(trimmed_lyr, 'onlandborder', "'Y'", 'PYTHON')
    DM.SelectLayerByAttribute(trimmed_lyr, 'SWITCH_SELECTION')
    DM.CalculateField(trimmed_lyr, 'onlandborder', "'N'", 'PYTHON')

    # identify coastal zones
    coastal_lyr = DM.MakeFeatureLayer(COASTLINE, 'coastal_lyr')
    DM.SelectLayerByLocation(trimmed_lyr, 'INTERSECT', coastal_lyr)
    DM.CalculateField(trimmed_lyr, 'oncoast', "'Y'", 'PYTHON')
    DM.SelectLayerByAttribute(trimmed_lyr, 'SWITCH_SELECTION')
    DM.CalculateField(trimmed_lyr, 'oncoast', "'N'", 'PYTHON')

    print("State assignment...")
    # State?
    DM.AddField(trimmed, "state", 'text', field_length='2')
    state_center = arcpy.SpatialJoin_analysis(
        trimmed,
        STATE_FC,
        'state_center',
        join_type='KEEP_COMMON',
        match_option='HAVE_THEIR_CENTER_IN')
    state_intersect = arcpy.SpatialJoin_analysis(trimmed,
                                                 STATE_FC,
                                                 'state_intersect',
                                                 match_option='INTERSECT')
    state_center_dict = {
        row[0]: row[1]
        for row in arcpy.da.SearchCursor(state_center, ['ZoneID', 'STUSPS'])
    }
    state_intersect_dict = {
        row[0]: row[1]
        for row in arcpy.da.SearchCursor(state_intersect, ['ZoneID', 'STUSPS'])
    }
    with arcpy.da.UpdateCursor(trimmed, ['ZoneID', 'state']) as cursor:
        for updateRow in cursor:
            keyValue = updateRow[0]
            if keyValue in state_center_dict:
                updateRow[1] = state_center_dict[keyValue]
            else:
                updateRow[1] = state_intersect_dict[keyValue]
            cursor.updateRow(updateRow)

    # glaciation status?
    # TODO as version 0.6

    # preface the names with the zones
    DM.DeleteField(trimmed, 'ORIG_FID')
    fields = [
        f.name for f in arcpy.ListFields(trimmed, '*')
        if f.type not in ('OID',
                          'Geometry') and not f.name.startswith('Shape_')
    ]
    for f in fields:
        new_fname = '{zn}_{orig}'.format(zn=zone_name, orig=f).lower()
        try:
            DM.AlterField(trimmed, f, new_fname, clear_field_alias='TRUE')
        # sick of debugging the required field message-I don't want to change required fields anyway
        except:
            pass

    DM.CopyFeatures(trimmed, output)

    # cleanup
    lyr_objects = [
        lyr_object for var_name, lyr_object in locals().items()
        if var_name.endswith('lyr')
    ]
    temp_fcs = arcpy.ListFeatureClasses('*')
    for l in lyr_objects + temp_fcs:
        DM.Delete(l)
Ejemplo n.º 4
0
env.workspace = wrk

#set the snapraster
#env.snapRaster = "C:/_Howard/SnapRasters/snapras30met"
env.snapRaster = "C:\\Users\\Public\\Rapunzel\\SnapRasters\\snapras30met"
env.cellSize = env.snapRaster
env.overwriteOutput = True
outCoord = env.snapRaster

# what's the name of the hypergrid
hyp = arcpy.ListRasters("hyp*", "All")[0]

# clip the hypergrid
print('clipping')
hyp_cl = Con(Raster(slf) >= 0, hyp, Raster(slf))
man.JoinField(hyp_cl, "VALUE", hyp, "VALUE", ["Richness"])

print('reclassifying')
# reclassify to four groups based on richness
# 0 = 0 (none)
# 1 = 1 (low)
# 2-4 = 2 (medium)
# 5 and up = 3 (high)

#get the max of the raster
rows = arcpy.SearchCursor(hyp_cl, "", "", "Richness", "Richness A")
val = 0
for row in rows:
    if val < row.Richness:
        val = row.Richness
del row
Ejemplo n.º 5
0
            print("working on " + rasName)
            man.CopyRaster(inRas, curHyp)
            man.BuildRasterAttributeTable(curHyp)
            man.AddField(curHyp, "spp0", "TEXT", "", "", 251)
            man.AddField(curHyp, "temp", "SHORT", 1)
            expr = "str( !Value! )"
            man.CalculateField(curHyp, "spp0", expr, "PYTHON")
        else:
            iminus = i - 1
            prevHyp = wrk + "/hyp" + str(iminus)
            print("working on " + elem + ", " + str(i) + " of " + str(listLen))
            curHyp = Combine([prevHyp, rasName])
            curHyp.save(wrk + "/hyp" + str(i))
            man.AddField(curHyp, "spp0", "TEXT", "", "", 251)
            jval = "hyp" + str(iminus)
            man.JoinField(curHyp, jval, prevHyp, "VALUE", ["spp0"])
            rasNoDot = rasName[0:rasName.find(".")]
            newCol = rasNoDot[0:11].upper()
            expr = "str(!spp0_1!) + str(!" + newCol + "!)"
            man.CalculateField(curHyp, "spp0", expr, "PYTHON")
            #clean up
            man.Delete(prevHyp)

# clean up a little more
man.DeleteField(curHyp, [jval.upper(), newCol, "spp0_1"])

#needed to continue below if you comment out the previous loop for any reason
#curHyp = wrk + "/hyp" + str(len(codeL)-1)

# expand information out to one col for each spp.
print("adding columns...")
Ejemplo n.º 6
0
for i in range(len(hypZ)):
    print("working on " + hypZ[i])
    # don't assume i is the class level -- extract class here
    classLevel = hypZ[i][-1:]
    curZo = wrk + "/zon_C" + classLevel
    # cycle through each edm
    for j in range(len(rasL)):
        if j == 0:
            inRas = inPath + "/" + rasL[j] + "_c.tif"
            curZoT_out = wrk + "/zonTab_C" + str(i) + "_" + str(j)
            print(".. zoning " + rasL[j])
            curZoT = ZonalStatisticsAsTable(hypZ[i], "Value", inRas,
                                            curZoT_out, "DATA", "MAXIMUM")
            man.CopyRaster(hypZ[i], curZo)
            man.AddField(curZo, "spp0", "TEXT", "", "", 251)
            man.JoinField(curZo, "Value", curZoT, "VALUE", ["MAX"])
            expr = "str( !MAX! )"
            man.CalculateField(curZo, "spp0", expr, "PYTHON")
            man.DeleteField(curZo, "MAX")
            man.Delete(curZoT_out)
        else:
            #jminus = j-1
            inRas = inPath + "/" + rasL[j] + "_c.tif"
            print(".. zoning " + rasL[j])
            curZoT_out = wrk + "/zonTab_C" + str(i) + "_" + str(j)
            curZoT = ZonalStatisticsAsTable(hypZ[i], "Value", inRas,
                                            curZoT_out, "DATA", "MAXIMUM")
            man.JoinField(curZo, "Value", curZoT, "VALUE", ["MAX"])
            expr = "str(!spp0!) + str(!MAX!)"
            man.CalculateField(curZo, "spp0", expr, "PYTHON")
            man.DeleteField(curZo, "MAX")