2

I am really lost and struggling because I have never used an Arc system before.

I have two datasets. One with house locations, and the other with investment locations- each locating by XY coordinate.

The room where I conduct my analysis only has ArcView, so I must use that.

I want to calculate the distance between a house and the nearest investment (calculate the distance between two XY coordinates).

Is this possible with ArcView?

I also want to join the variables in the investment dataset to the housing dataset, after I have calculated the nearest distance. Is that possible?

I am sorry if I am not explaining myself correctly- I am just very confused, if it's not stata, then I don't know how to use it!

  • 1
    Sounds like you want to do a spatial join: resources.arcgis.com/en/help/main/10.1/index.html#//… From memory, this should be available in ArcView. – nagytech Jun 1 '15 at 12:59
  • Are you using an ArcView level license of ArcGIS for Desktop? If so, which version? Or the old ArcView 3 product which is very different? – PolyGeo Jun 1 '15 at 20:22
  • As far as I know it's the latter! – Kelly Jun 2 '15 at 10:13
0

You can do this a couple of ways (manually or with a script or model). You will likely end up using the Point Distance Tool which will identify the closest investment location to each point in a table and that table can then be joined back to the house location layer with a tabular join. Point Distance is in the toolbox under "Analysis Tools" -> "Proximity".

Editing the table: This is going to give you every distance from every house to every location so you can open this in Excel and filter out what you need or just edit the table to include just the shortest distance for every "FID". There are a few ways to go about this. You could just select the shortest distance for each FID and then export the table.

If you have too many features to make this doable (even with Excel) then you would need to figure out a script or model to select just the records with the shortest distance.

Point Distance Tool dialog

Use the house locations as input features and the investment locations as near features. Look at the table after this runs. You may need to manipulate the table a little bit to get it into the form that you want but you can join this back to your original house location layer by some unique id from that layer.

You can right click the house locations layer and choose "Joins and Relates" -> "Join...". Make sure "Join attributes from a table is selected at the very top. Then choose the field that the join will be based on in the house locations. Choose your table from the Point Distance tool in the 2nd option and the field that matches.

  • Feel free to use the green checkbox under the rating for this answer to select it as the solution. – jbchurchill Jun 1 '15 at 14:09
0

This seems like a repeat post from your earlier question here, so please don't post twice. Since you mentioned you were working with an ArcView (i.e. Basic) license, I wonder how you're able to use the Point Distance tool, which requires Advanced?

For those who have Basic/Standard, ESRI's Near algorithm isn't too hard to implement yourself in Python. The following script shows an example of how to write such an algorithm from scratch and will work on any license level. If you don't have luck with the above suggestion, try this script. It's written as a tool, but you can write the GetParamaterAsTexts as hardcoded paths and the SetProgressorLabels as standard prints if you were to run it in the interpreter. The "plumb lines" (my ad-hoc word btw) are an easy way to visualize the connections between the "Input" and "Near" (or "Source" and "Target") features.

__author__ = "John K. Tran"
__contact__ = "jtran20@masonlive.gmu.edu"
__version__ = "2.0"
__created__ = "6/11/15"

"""Compares all target point features to all source point features and populates
the ID and distance of each target with the nearest source. Can optionally create
plumb lines to visualize the links between source and target featues."""

import arcpy
import os
import math
import random

arcpy.SetProgressor("Default", "Firing up script...")

# Set up initial parameters for script.
source = arcpy.GetParameterAsText(0) # Point feature class
target = arcpy.GetParameterAsText(1) # Point feature class
sourceIDfield = arcpy.GetParameterAsText(2) # Field to identify unique ID of Source values
targetIDfield = arcpy.GetParameterAsText(3) # Field to identify unique ID of Target values
createplumblines = arcpy.GetParameterAsText(4) # Optional output location for plumb lines. Can leave blank if desired.
arcpy.env.parallelProcessingFactor = "100%"

#Convert arcpy field types for "Field Type" argument in AddField_management.
fieldtypedict = {"Blob":"BLOB", "Date":"DATE", "Double":"DOUBLE", "Guid":"GUID", "Integer":"LONG", "Raster":"RASTER", "Single":"FLOAT", "SmallInteger":"SHORT", "String":"TEXT", "OID":"LONG"}

# Get the field type for the source ID field, so we can make analogous field for NearID in target.
sourcefields = arcpy.ListFields(source)
targetfields = arcpy.ListFields(target)
sourceIDfieldtype = fieldtypedict[[field.type for field in sourcefields if field.name == sourceIDfield].pop()]

# Get the spatial references for source and target and make sure they're the same.
sourcespatialref = arcpy.Describe(source).spatialReference
targetspatialref = arcpy.Describe(target).spatialReference
assert sourcespatialref.name == targetspatialref.name, "The source and target must have the same coordinate system. Ensure both data are in an identical projected coordinate system."

# Create a "NearestID" field in the target fc if one isn't available.
arcpy.SetProgressorLabel("Adding Fields")
if "NearestID" not in [field.name for field in targetfields]:
    arcpy.AddField_management(target, "NearestID", sourceIDfieldtype)
if "NearestDist" not in [field.name for field in targetfields]:
    arcpy.AddField_management(target, "NearestDist", "FLOAT")

# Create a Point class with a distance method. It's more efficient than the native arcpy.Geometry object, which has many additional overhead functions.
class Point(object):
    def __init__(self, x, y, ID):
        """Create the constructor to initialize the point."""
        self.x = x
        self.y = y
        self.ID = ID
    def GetDist(self, OtherPoint):
        """Determines the distance between two points using Pythagorean Theorem."""
        return math.sqrt((self.x-OtherPoint.x)**2+(self.y-OtherPoint.y)**2)

# Create a list of source points to compare with each target point.
scount = 0
sourcepoints = list()
with arcpy.da.SearchCursor(source, ["SHAPE@XY", sourceIDfield]) as sourcecursor:
    for row in sourcecursor:
        if scount % 100 == 0:
            arcpy.SetProgressorLabel("Gathering Source Points: {0} features complete".format(str(scount)))
        sourcepoint = Point(row[0][0], row[0][1], row[1])
        sourcepoints.append(sourcepoint)
        scount += 1
if "sourcecursor" in dir():
    del sourcecursor

# Create several startup variables if creating plumb lines was enabled.
if createplumblines:
    targetpoints = list()
    closestpoints = list()
    arcpy.CreateFeatureclass_management(os.path.dirname(createplumblines), os.path.basename(createplumblines), "POLYLINE", None, "DISABLED", "DISABLED", targetspatialref)
    arcpy.AddField_management(createplumblines, "ID", sourceIDfieldtype)

# Loop through each target and compare with each source.
# Keep the lowest distance source and populate ID and Distance fields in target.
count = 0
with arcpy.da.UpdateCursor(target, ["SHAPE@XY", targetIDfield, "NearestID", "NearestDist"]) as targetcursor:
    for row in targetcursor:
        if count % 100 == 0:
            arcpy.SetProgressorLabel("Computing Distance and Populating Target: {0} features complete".format(str(count)))
        targetpoint = Point(row[0][0], row[0][1], row[1])
        closestsource = None
        closestdist = 100000000.0 # Set some arbitrarily large distance for initial comparison.
        for sourcepoint in sourcepoints:
            currentdist = targetpoint.GetDist(sourcepoint)
            if currentdist < closestdist:
                closestdist = currentdist
                closestsource = sourcepoint
        row[2] = closestsource.ID
        row[3] = closestdist
        targetcursor.updateRow(row)
        if createplumblines:
            targetpoints.append(targetpoint)
            closestpoints.append(closestsource)
        count = count + 1
if "targetcursor" in dir():
    del targetcursor

# Create the plumb lines if the option was enabled.
if createplumblines:
    zippoints = zip(closestpoints, targetpoints)
    plumbcursor = arcpy.da.InsertCursor(createplumblines, ["SHAPE@", "ID"])
    for source, target in zippoints:
        sourcepnt = arcpy.Point(source.x, source.y)
        targetpnt = arcpy.Point(target.x, target.y)
        plumbarray = arcpy.Array([sourcepnt, targetpnt])
        plumbline = arcpy.Polyline(plumbarray)
        plumbcursor.insertRow((plumbline, source.ID))
    if "plumbcursor" in dir():
        del plumbcursor

arcpy.ResetProgressor()

The results will look similar to this (although this screenshot was done comparing points to lines). The "Target" FC will have 2 fields appended named "NearestID" and "NearestDist". The "Plumb Lines" will show the actual paths to the nearest feature. Its attribute table will also contain additional info.

enter image description here

Let me know if you have any issues running the script. It works for point-to-point geometry comparisons.

  • I joined the website just over a month, since then I have become aware of the rules of posting questions and I now know I have the ability to edit edit previous questions. A month go, I first used Arc View. I have since downloaded the free trial of advanced from the ESRI website, since it was not possible on Arc View. I am now using the proximity tools. Thank you for your help and expertise John. Best wishes – Kelly Jul 7 '15 at 9:36
  • Gotcha, sure, no problem! – John Jul 7 '15 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.