Attribute Rule for Line intersecting a Polygon (Street in Municipality)

541
1
01-20-2020 04:45 PM
KatjaKrivoruchko1
New Contributor

I need to create an attribute rule that would populate what community a road centerline falls into. For the most part, a centerline falls wholly within a community, so right and left of the line will have the same community, but some centerlines run along the boundary, and have different values for community on the left and the right. The centerline should be split whenever it crosses a boundary (so there are ever only one or two communities that a properly digitized centerline would intersect).

I can write the regular case (expecting just one community in the collection) and outputting an error when the line falls wholly outside a community or there are more than two communities in a collection:

var polyField = FeatureSetByName($datastore, "COMMUNITIES", ["COMMUNITY"])
var polyFeatures = Intersects(polyField, $feature)
if (Count(polyFeatures)=1){
var polyFeature = First(polyFeatures);
return polyFeature.COMMUNITY}
else if (Count(polyFeatures)>2) or (Count(polyFeatures)<1)) {
<RETURN ERROR HERE>}

What I really need, however, is to figure out what community lies to the left and which one to the right of the digitized direction of the centerline when there are two communities in the collection. Is there a way to do that in Arcade?

Tags (1)
1 Reply
XanderBakker
Esri Esteemed Contributor

Hi Katja Krivoruchko ,

In order to determine the left and right polygon of a line, the line would have to be able to split the polygon. This may not be the case in your situation. There might be a way by creating points left and right of the line and use those to query the left and right polygons. 

In case you want to know which polygons are crossed you can do something like this:

var polyField = FeatureSetByName($datastore, "COMMUNITIES", ["COMMUNITY"]);
var polyFeatures = Intersects(polyField, $feature);

var community = "No community found";
var cnt = Count(polyFeatures);
if (cnt == 1) {
    var polyFeature = First(polyFeatures);
    community = polyFeature.COMMUNITY;
} else if (cnt > 1) {
    var i = 0;
    for (var polyFeature in polyFeatures) {
        i++;
        if (i == 1) {
            community = polyFeature.COMMUNITY;
        } else {
            community += ", " + polyFeature.COMMUNITY;
        }
    }
}

return community;

This will create a comma separated string with the list of municipalities. Please note that this example it does not return the value according the format used in an attribute expression.

You can also determine the percentage a line crosses each municipality:

var polyField = FeatureSetByName($datastore, "COMMUNITIES", ["COMMUNITY"]);
var polyFeatures = Intersects(polyField, $feature);

var community = "No community found";
var cnt = Count(polyFeatures);
if (cnt == 1) {
    var polyFeature = First(polyFeatures);
    community = polyFeature.COMMUNITY;
} else if (cnt > 1) {
    var tot_len = Length($feature, 'meters');
    for (var polyFeature in polyFeatures) {
        i++;
        var road_part = Intersection($feature, polyFeature);
        var percentage = Length(road_part, 'meters') / tot_len * 100.0;
        if (i == 1) {
            community = polyFeature.COMMUNITY + " (" + Round(percentage, 1) + "%)";
        } else {
            community = TextFormatting.NewLine + polyFeature.COMMUNITY + " (" + Round(percentage, 1) + "%)";
        }
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

It might also be possible to create an attribute rule that would trigger when creating a new line, and that could check for the polygons and split the line up according to each municipality. This would have some additional complexity when editing existing lines and dragging vertices across borders.