Subscribe to this thread
Home - General / All posts - Left/Right buffer or offset
otm_shank
39 post(s)
online
#11-Aug-17 04:43

Hi, one of the things I was hoping to do with Radian Studio is create Address Ranges, for use in geocoding routines (i.e. for interpolating missing address numbers). This involves taking an address point file and a street lines file, and determining a 'minimum' and 'maximum' address number per street segment, however it needs to be done per 'side' of the street, i.e. FromLeft, ToLeft, FromRight, ToRight. ('Side' is relative to the drawing direction of the line)

Thanks to Art's informative blog, I can (hopefully) use SQL to determine the nearest street segment for each address point where the street name values match, and then determine a min and max address number. However, I'm not sure how to do this per side of the street.

I was hoping to do either a one-sided buffer, or a tiny offset (e.g. 1m) in either direction, however I don't think these are possible yet in Radian Studio? Are there any plans to introduce one-sided buffers, capped ends etc?

Also I'd appreciate if anyone else has any good ideas on how to achieve this using some other method!

Thanks, Tim

Dimitri


4,196 post(s)
#11-Aug-17 06:39

I don't think these are possible yet in Radian Studio?

Pretty much everything is possible. More precisely the question is whether a particular capability you seek is provided as a pre-built command.

That's not just a spinning logic for the sake of spinning logic distinction, either... it's a practical distinction in a system where, ideally, a limited number of well-formed commands and capabilities can be recombined in limitless ways to achieve any desire.

So asking, "is it possible" can result in a "sure... do this" in a description that involves just one step with one command, or, perhaps, a couple of steps with different commands, and so on until at some point there is a sequence of moves that is pretty lengthy and may be clear to an expert but which isn't possible for most.

Within that gray area between one-click-wonders and a paragraph of SQL only Tim and Adam understand, is where one must draw the line between "dedicated, canned command" and "this is the magic of recombining a limited number of general commands..."

In the case above, here is one thought experiment way to create a one-sided buffer is a) draw the full buffer on the line you want and put it aside. b) Now, draw a slightly bigger buffer on the same line. c) Extend the last segments of the line at both ends to some distance greater than the bigger buffer distance, you now have a line that extends beyond the boundaries of that bigger buffer. d) Use that longer line to split the bigger buffer into two parts and delete the part on the side you don't want. e) Intersect the remaining half with the original buffer in a) above, and that is your one-sided buffer. Sounds long but it probably could be written as a very compact SQL expression.

You could do the same with all of the other canned forms of buffers (capped ends, etc.) one encounters in, say, Arc.

Whether it makes sense to do those as one-step, dedicated commands in Radian or in 9 is entirely up to a mix of initial engineering based upon Suggestions received to date (read the Suggestions page to see how the process works) and then as modified thereafter by future Suggestions. I haven't specifically searched that database of suggestions but off the top of my head in 20 years I don't think I've ever seen a suggestion recommending capped end buffers or one sided buffers, so I doubt that will bubble up in priority. It could be one reason such suggestiosn aren't there is that with Release 8 such things are very easy to do with simple combinations of existing, interactive editing commands.

To get deeper insight and lookahead on what is planned, join the process as 9 starts rolling out. That will be very soon now and in a way that will be even easier to join and participate than the beta process for Radian.

adamw


7,159 post(s)
#11-Aug-17 07:11

We don't have one-sided buffers as a built-in function. We can certainly provide such a function in the future.

Could you clarify what specifically you want to achieve?

Here is my current understanding, please correct me if I get anything wrong: (a) you have an address with a building number, (b) you will somehow (say, via a query) determine that the address appears on a particular line, (c) the line has FromLeft / ToLeft / FromRight / ToRight values for building numbers, the direction of the line matters, (d) you want to place the building onto a line, creating a point object with the approximate coordinates of the building, moving the point to either left or right side depending on what side the building seems to be. Correct?

If so, I don't think you need one-sided buffers. With the building number from the address and the ranges from the line in hand, you determine whether the address is on the left or right side. Then you compute how far along the address is on the line (length of the line * (address - fromX) / (toX - fromX), with some handling for reversed or empty ranges). Then you compute the coordinate on the center of the line at that location. Then you find out what segment the coordinate belongs to (dx, dy), compute a normal to that segment (-dy, dx), orient the normal according to whether you want left or right (reverse both signs = dy, -dx, if you want the right side), then you go in that direction from the coordinate on the center of the line for X meters.

Currently, it is best to do the above using a script function - that is, write a script function that would take line geometry + FromLeft / ToLeft / FromRight / ToRight + building number from the address, and return a point computed as described above, then call it from a query. In the future, we are going to provide built-in (query) functions for various parts. We have several planned already.

otm_shank
39 post(s)
online
#11-Aug-17 11:28

Hi Adam, that's not quite it. The interpolated geocoding function in the GIS works pretty much in the way you've described. What I'm referring to is actually calculating the FromLeft, ToLeft, FromRight, ToRight values in the first place.

So per street segment, I need to find address points which fall on the left, determine the min (e.g. 12) and max (e.g. 26) address numbers in this set, and also determine the order relative to the draw direction, i.e. 12-26 or 26-12. And I then need to do the same for the right side of the street segment.

So being able to do a small left/right buffer would make it possible to determine which points 'belong' to a segment, and on which side.

Thanks, Tim.

adamw


7,159 post(s)
#11-Aug-17 12:08

Got it.

You have buildings with numbers and lines for streets, and you need to assign building ranges for each street. For that, you are planning to take each street, build left / right side buffers with some small distance, see what buildings are in each buffer and compute from / to ranges.

If I got it correct, I can see why you want left / right buffers.

They will produce conflicts (in the screen below, the blue points will be both in the left-side and the right-side buffer no matter the direction of the line), but I guess you could deal with them manually:

An alternative approach is to take all points within a certain distance of the line, for each point find the closest segment of the line and see if the turn from the segment to the point is left or right (that's a fairly simple formula). It won't solve the issue of conflicts, however, conflict points will just be assigned to whichever segment happened to be slightly closer.

Attachments:
side-buffers-conflict.png

otm_shank
39 post(s)
online
#11-Aug-17 12:38

see if the turn from the segment to the point is left or right

Can this be done within SQL? Or would I need to write a script to loop through each line segment/node and work this out?

adamw


7,159 post(s)
#11-Aug-17 14:04

Both locating a segment and checking the direction of a turn can be done in SQL, but a script function would work faster.

Selecting closest segment in SQL, for example, looks like this (the query assumes a table of lines called Lines and computes a closest segment to a fixed coordinate on each line):

--SQL9

FUNCTION ClosestSegment(point GEOM, line GEOMTABLE AS (

  SELECT * FROM (

    SELECT xy, xynext, GeomDistance(GeomMakeSegment(xy, xynext), point, 0) AS d

    FROM CALL GeomToSegments(line)

  ) ORDER BY d ASC FETCH 1

END;

SELECT mfd_id,

  SPLIT CALL ClosestSegment(GeomMakePoint(VectorMakeX2(50, 60)), geom)

FROM lines;

The ClosestSegment function: takes a line, splits it into segments (GeomToSegments), computes a distance from point to each segment (GeomDistance), orders the segments by computed distance, and selects the segment with the shortest distance.

Computing the direction of a turn is even easier: "orientation" in this picture.

otm_shank
39 post(s)
online
#11-Aug-17 22:06

Awesome! Thanks Adam, I'll work through your example to understand it.

lionel94 post(s)
#12-Aug-17 02:29

Does radian has specific type for manage matrix data and matrix operator ?

Most of the time matrix are not available by default with the language.

Pythons has Numpy for manage matrix fonction name and i know it ll be easy import since i already test tcltk with python inside manifold v8.

The svg demo in radian use matrix transformation but not using matrix syntax but linear syntaxe ( raw addition and multiplication ).

How matrix javascript library can be install and call from javascript use inside radian . The documentation give example using creation of name function ( create and call ) for fibonacci but don't read in documentation of radian for javascript the way to create and import js file library inside radian . Does nodejs context and loader are available From radian javascript script ? ( nodejs is base on v8 ) .....

The power of nodejs is because there is npm ( remote library / package using http protocol git or others ) and loaders like webpack for not only js but image css .....

I ll search in radian the sql function tata use vector geommakepoint seum one if those in sql context

lionel94 post(s)
#12-Aug-17 03:16

All is cover in radian documentation : script and command article. $reference must be use using a absolute path .

lionel94 post(s)
#13-Aug-17 03:32

Hi

Could we have a map file to test study the SQL function ClosestSegment ?

Thank's

adamw


7,159 post(s)
#13-Aug-17 06:41

Sure.

Here is a MAP file with an example drawing of lines and the query above that computes a closest segment to a fixed location for each. I put a point at the queried location into the drawing as well.

Attachments:
query-closest-segment.map

lionel94 post(s)
#13-Aug-17 14:07

Thank

i ask myself what is the 50 60 point so this point is in the drawing for information but hard code in the query .

Manifold User Community Use Agreement Copyright (C) 2007-2017 Manifold Software Limited. All rights reserved.