How can I transform a polygon into a point?

1622
14
11-16-2017 02:24 PM
GB
by
New Contributor

Hi!

I have  a shapefile with polygons, but I want to transform these objects into points (example: I have the polygons with are the physical borders of a subset of school, I want to have point rather than the polygon of the building).

What can I use?

- feature to points doesn't suit me because it creates a new output, while I would like to keep the information I have in my original shapefile.

-I tried add geometry attributes, it runs successfully, but it doesn't not add the geometry attributes!!! Do you know why it happens?

Do you have other solutions?

Thank you!!

0 Kudos
14 Replies
XanderBakker
Esri Esteemed Contributor

In support of what Dan Patterson has been saying:

  • You cannot change the feature type from polygon to point. Furthermore, you shouldn't! You can always create a new featureclass that represents the polygons as points, but you will never be able to get back to this more precise polygon representation based on the points if you overwrite the original polygons. In theory you can, by creating a temporal point featureclass from the polygons, delete the polygon featureclass and rename the points. But once again, you shouldn't!

Did you try the toolbox I posted earlier to create a new point featureclass from the polygons? It shouldn't be difficult.

0 Kudos
JayantaPoddar
MVP Esteemed Contributor

Feature to Point (Data Management) should work for you (Requires ArcGIS Desktop Advanced license). The attributes of the input features will be maintained in the output feature class. In case of multipart polygon, the centroid might lie outside the polygon.

I will say "Give it a try".



Think Location
XanderBakker
Esri Esteemed Contributor

In case you do not have access to an Advance license you could create a tool that does this for you with a Basic license.(sorry for the Spanish interface)

  • first parameter is the polygon featureclass
  • second parameter is the output point featureclass
  • third parameter is the method

The code beneath looks like this:

#-------------------------------------------------------------------------------
# Name:        FeatureToPoint.py
# Purpose:     Convertir feature a punto
#
# Author:      xbakker
#
# Created:     02/03/2015
#-------------------------------------------------------------------------------
import arcpy
import os
import math

def main():

    # parameters
    fc_in = arcpy.GetParameterAsText(0)
    fc_out = arcpy.GetParameterAsText(1)
    method = arcpy.GetParameterAsText(2) # CENTROID, INSIDE

    # fld para poder hacer el join con la entrada
    fld_oid_in = "ORIG_FID"

    # geometria de salida
    geomtype = "POINT"
    sr = arcpy.Describe(fc_in).spatialReference

    # recreate fc_out based on fc_lines (in)
    ws_name, fc_name = os.path.split(fc_out)
    createFeatureClass(fc_out, fc_in, geomtype, sr)

    # add OID field
    arcpy.AddField_management(fc_out, fld_oid_in, "LONG")

    # cursors:
    cnt = 0
    flds_out = ("SHAPE@", fld_oid_in)
    with arcpy.da.InsertCursor(fc_out, flds_out) as curs_out:
        flds_in =("SHAPE@", "OID@")
        with arcpy.da.SearchCursor(fc_in, flds_in) as curs:
            for row in curs:
                feat = row[0]
                oid = row[1]

                # get point based on method
                pnt = getPoint(feat, method)

                # store point
                cnt += 1
                if cnt % 100 == 0:
                    arcpy.AddMessage("Procesando feature: {0}".format(cnt))
                curs_out.insertRow((pnt, oid, ))

    arcpy.AddMessage("{0} features procesados...".format(cnt))


def getPoint(feat, method):
    """Convertir feature a punto dependiendo del metodo y tipo de geometria"""

    pnt = None
    if method == "CENTROID" and feat.type == 'polygon':
        pnt = feat.centroid

    elif method == "CENTROID" and feat.type == 'polyline':
        pnt = CentroidPolyline(feat)

    elif method == "CENTROID" and feat.type == 'multipoint':
        # average x and y coordinates of all the points in the multipoint feature
        pnt = CentriodMultiPoint(feat)

    elif method == "INSIDE" and feat.type == 'polygon':
        pnt = feat.labelPoint

    elif method == "INSIDE" and feat.type == 'polyline':
        pntg = feat.positionAlongLine(0.5, True)
        pnt = pntg.firstPoint

    elif method == "INSIDE" and feat.type == 'multipoint':
        pnt = InsideMultiPoint(feat)

    return pnt


def InsideMultiPoint(feat):
    # punto mas cercano al centroid
    pnt_c = CentriodMultiPoint(feat)
    min_dist = 999999
    for pnt_mp in feat:
        dist = getDistance(pnt_mp, pnt_c)
        if dist < min_dist:
            pnt = arcpy.Point(pnt_mp.X, pnt_mp.Y)
            min_dist = dist
    return pnt

def CentriodMultiPoint(multipoint):
    lst_x = []
    lst_y = []
    for pnt in multipoint:
        lst_x.append(pnt.X)
        lst_y.append(pnt.Y)

    return arcpy.Point(sum(lst_x)/float(len(lst_x)), sum(lst_y)/float(len(lst_y)))


def CentroidPolyline(polyline):
    """weighted average x and y coordinates of the midpoints of all line segments in the line feature
       where the weight of a particular midpoint is the length of the correspondent line segment"""
    lst_x = []
    lst_y = []
    lst_length = []
    for part in polyline:
        prev_pnt = None
        for pnt_part in part:
            if prev_pnt is None:
                # skip
                prev_pnt = arcpy.Point(pnt_part.X, pnt_part.Y)
            else:
                dist = getDistance(pnt_part, prev_pnt)
                line = arcpy.Polyline(arcpy.Array([prev_pnt, pnt_part]))
                mid_pnt = line.positionAlongLine(0.5, True)
                lst_x.append(mid_pnt.firstPoint.X * dist)
                lst_y.append(mid_pnt.firstPoint.Y * dist)
                lst_length.append(dist)

    sum_dist = sum(lst_length)
    sum_x = sum(lst_x)
    sum_y = sum(lst_y)
    x = sum_x / sum_dist
    y = sum_y / sum_dist
    return arcpy.Point(x, y)

def createFeatureClass(fc_out, fc_in, geomtype, sr):
    ws_name, fc_name = os.path.split(fc_out)
    arcpy.CreateFeatureclass_management(ws_name, fc_name, geomtype, spatial_reference=sr)

def getDistance(pnt1, pnt2):
    return math.hypot(pnt1.X - pnt2.X, pnt1.Y - pnt2.Y)

if __name__ == '__main__':
    main()
GB
by
New Contributor

I fogot to ask something in my previous reply.

Summing up: I added two fields in the original feature class (contening polygons), I calculated the X and Y coordinates of the centroid, I created a XY event by going to data management tools, layers and table views, make xy event. When I open the attribute table, I find two fields with the shape, and the geometry is polygon. (see attachment). Why is that happening? I can visualize points on the map.

0 Kudos
XanderBakker
Esri Esteemed Contributor

This is very strange. When you use XY events they will always create point geometry. 

0 Kudos