MapInfo Pro Developers User Group

 View Only
Expand all | Collapse all

Trying to draw a shape being line, arc, line

  • 1.  Trying to draw a shape being line, arc, line

    Posted 09-14-2022 21:55
    Hello,

    I have 3 points.
    Point #1, point #2 and point #3



    I am trying to draw a line from point #1 to point#2 (create line) then an arc from point #2 to point #3 (create arc), then line from point #3 to point #1 (create line).
    When I use update set obj = createline, it will wipe off the previous drawing.

    So, is there a command to do this please?
    Thanks

    ​​​​​​​​​

    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------


  • 2.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-15-2022 02:14
      |   view attached
    Hi Alban

    It seems you are trying to create a sector.

    Does your arc really have to be an arc, or could it be a polyline with "many" points describing an arc?

    Some years back I described how you can create a function that would create an Annulus Sector:
    A Sector is created from a circle whereas an annulus Sector is created from a doughnut.

    Four examples of annulus sectors - the top right is a sector - it starts at the center of the circle.
    All four have been created with the function below.


    If you pass a value of 0 for the fInnerRadius the function below will return a Sector.

    Function CreateAnnulusSector( ByVal oCenterPoint As Object
    , ByVal fInnerRadius As Float 'in meters
    , ByVal fOuterRadius As Float 'in meters
    , ByVal fStartAngle As Float
    , ByVal fEndAngle As Float
    , ByVal nResolution As Integer
    ) As Object

    Dim oSector, oCutter As Object,
    fAngle, fRotatedAngle, fX, fY, fDistance As Float,
    i As Integer

    CreateAnnulusSector = oCenterPoint

    '**Create concentric circle
    oSector = CartesianBuffer(oCenterPoint, nResolution, fOuterRadius, "m")
    If fInnerRadius > 0 Then
    oSector = Erase(oSector, CartesianBuffer(oCenterPoint, nResolution, fInnerRadius, "m"))
    End If

    '**Find center coordinates
    fX = CentroidX(oCenterPoint)
    fY = CentroidY(oCenterPoint)
    '**Calculate distance for cutter object
    fDistance = 3 * fOuterRadius

    Create Pline Into Variable oCutter
    1 (fX, fY)
    Alter Object oCutter
    Node Add ( fX + ((Cos(fStartAngle * DEG_2_RAD)) * fDistance)
    , fY + ((Sin(fStartAngle * DEG_2_RAD)) * fDistance))
    Alter Object oCutter
    Node Add ( fX + ((Cos(fEndAngle * DEG_2_RAD)) * fDistance)
    , fY + ((Sin(fEndAngle * DEG_2_RAD)) * fDistance))

    '**Convert cutter polyline to a polygon
    oCutter = ConvertToRegion(oCutter)
    '**Erase the concentric circle where the cutter object doesn't overlap
    oSector = Overlap(oSector, oCutter)

    CreateAnnulusSector = oSector

    End Function

    I have also attached an mb file with the function and an example of how you can use the function. You can run the application in MapInfo Pro with a map window open. The annulus sectors will be created based on the center of the map and the zoom of the map.

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------

    Attachment(s)

    zip
    AnnulusSector.zip   2 KB 1 version


  • 3.  RE: Trying to draw a shape being line, arc, line

    Posted 09-15-2022 02:36
    Hello,

    Exactely what I need...Yes, I am displaying sectors.
    I the meantime, I wrote this... Basically it creates 2 lines and an arc... but the script takes quite a long time to run.
    It also needs to have 3 points I am processing via SQL.

    I reckon your way is much more efficient.
    Thanks a lot for your help.


    '***************************
    'Sub Procedure:CreateLineArc
    '***************************


    Sub CreateLineArc
    Dim Obj1 as Object 'Line
    Dim Obj2 as Object 'Arc
    Dim Obj3 as Object 'Line
    Dim Obj4 as Object 'Combined Objects
    Dim start_angle, end_angle as Float
    Dim i as integer

    i=0

    Fetch First From test_cut

    While Not EOT (test_cut)

    i=i+1

    'print test_cut.actual_longitude
    'print i
    Create Line into Variable Obj1 ( test_cut.actual_longitude, test_cut.actual_latitude) ( test_cut.Longitude2a, test_cut.Latitude2a)
    'Create Arc into Variable Obj2 ( test_cut.Longitude2a, test_cut.Latitude2a) ( test_cut.Longitude2b, test_cut.Latitude2b) 90 30
    Obj2 = Exec("MapCAD.mbx","ArcFromPointsXY", test_cut.Longitude2a, test_cut.Latitude2a, test_cut.Longitude2, test_cut.Latitude2, test_cut.Longitude2b, test_cut.Latitude2b)
    Create Line into Variable Obj3 ( test_cut.actual_longitude, test_cut.actual_latitude) ( test_cut.Longitude2b, test_cut.Latitude2b)

    Obj4 = Combine (Combine( Obj1, Obj2) , Obj3)
    'Obj4 = Combine ( Obj1,Obj3)


    Update test_cut set obj = Obj4 where Rowid = i

    Fetch Next From test_cut
    wend


    end sub

    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 4.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-15-2022 03:00
    Hi Alba

    I'd assume there are two things that slow down your script:

    1. Calling a function in another running application, in your case MapCAD.

    I would assume this would be slower than using a built-in function in MapBasic or a function in your own application. Not something I have tested, however.

    2. Looping through the records in your table

    If possible we advise the use of a function that can be used in for example an update statement over looping through the table.

    In your example, you could have created a function called CreateLineArc that takes the needed parameters. You could then have used this in an update statement like this:

    Update test_cut 
       Set OBJ = CreateLineArc(actual_longitude, actual_latitude, Longitude2, Latitude2, Longitude2a, Latitude2a)


    where you pass the column names as parameters for the function. MapInfo Pro will then pass over the actual values for each record as the Update statement runs through the records.

    Projected Coordinate System version Longitude/Latitude

    Og, I notice that you are using lat/long values. You probably want to change my function to use Lat/Long too.
    Currently, it's for example using CartesianBuffer. Change that to the plain Buffer function.

    And the method for calculating points for the cutter object, you will need to change that from:
    Alter Object oCutter
    Node Add ( fX + ((Cos(fStartAngle * DEG_2_RAD)) * fDistance)
    , fY + ((Sin(fStartAngle * DEG_2_RAD)) * fDistance))
    to

    oPoint = Offset(oCenterPoint, fStartAngle , fDistance, "m")

    Alter Object oCutter
    Node Add (CentroidX(oPoint))
    , CentroidY(oPoint))
    And add Dim oPoint As Object to the list of variables.

    Does that make sense?

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 5.  RE: Trying to draw a shape being line, arc, line

    Posted 09-16-2022 01:46
    Hello Peter,

    Thanks for the reply.

    I followed your recommendation, i.e point #2, This is now half quicker. So good outcome.
    Now, I updated your mb file to use lat/long. I finally got it to work after spending quite some time trying to underatnd why sectors where not pointing to the right azimuth. It looks like offset() command uses X as 0, so I did remove 90deg:

    oPoint = Offset(oCenterPoint, 90-fStartAngle , fDistance, "m")

    Is this the right way?

    No, in terms of performance, it is very slow to run. Is it because I did a loop in the Main Sub to browse my table?
    Without the loop, it just process one row.

    Thanks​​

    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 6.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-16-2022 02:31
    Hi Alban

    1. Azimuth
    Yeah, the problem could be that the tool is expected directions in the way MapInfo Pro assumes them: East is 0 degrees and then counter-clockwise. This means North is 90 degrees, West is 180 and South is 270 degrees.

    There are multiple other ways to calculate directions, such as North is 0 and then clockwise.

    Do you know how your direction is measured?

    If we know, I may have a function that can convert it to the value MapInfo Pro expects if it's more complicated than subtracting 90 degrees.

    2. Performance
    Can you share your code for updating your table?

    You should be able to do something like this in the main sub:
    Update test_cut
     Set OBJ =
    CreateAnnulusSector(CreatePoint(actual_longitude, actual_latitude), 0, 250, AZIMUTH - 30, AZIMUTH + 30, 60)
    where 
    • test_cut is your table
    • actual_longitude is the column with your longitude
    • actual_latitude is the column with your latitude
    • 0 is the inner radius
    • 250 is the outer radius, can also be a column name
    • AZIMUTH is the column with the direction of the sector
    • 60 is the resolution/number of points for a full circle


    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 7.  RE: Trying to draw a shape being line, arc, line

    Posted 09-16-2022 03:08
      |   view attached
    Hello Peter,

    1)  The bearings are based on true north. 0 to 360deg. I haven't check too much the impact of removing 90deg, Does Mapinfo understand negative bearings or it needs to be normalised again to 360deg?

    2) I attached the Mb file.

    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------

    Attachment(s)

    txt
    sector_v2.txt   3 KB 1 version


  • 8.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-16-2022 03:40
      |   view attached
    Hi Alban

    I think we are getting there

    1. I have modified your Main sub to this:
    Sub Main

    Set CoordSys Table Live_Cell
    Update Live_Cell
       Set OBJ = CreateAnnulusSector(CreatePoint(actual_longitude, actual_latitude), 0, Radius, MathNorth2MathAngle(Brg2a), MathNorth2MathAngle(Brg2a), 120)

    End Sub

    2. I have removed the 90- in the CreateAnnulusSector function. The statements now look like this:
    oPoint = Offset(oCenterPoint, fStartAngle , fDistance, "m")
    Alter Object oCutter Node Add (CentroidX(oPoint),CentroidY(oPoint))
    oPoint = Offset(oCenterPoint, fEndAngle , fDistance, "m")
    Alter Object oCutter Node Add (CentroidX(oPoint),CentroidY(oPoint))

    I also removed unnecessary variables from the CreateAnnulusSector function

    3. I have added a new function that converts your North angle to a Math angle. Hopefully, it works

    Please find a modified version of your code.

    Let me know how that goes

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------

    Attachment(s)

    txt
    SectorToolAlban.txt   2 KB 1 version


  • 9.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-16-2022 04:46
    Hi Alban

    I also just realize that I do have a different AnnulusSecotr function in the OBJLib module that is part of the MapBasic Library.

    That function takes the direction and the width of the sector instead of the two and from angles:

    OBJCreateAnnulus( ByVal oCenter As Object
       , ByVal fDirection As Float
       , ByVal fRadiusInner As Float 'meters
       , ByVal fRadiusOuter As Float 'meters
       , ByVal fAngleWidth As Float
       , ByVal nResolution As Integer
       , ByVal nCalculationMethod As Integer 'CALC_METHOD_CARTESIAN / CALC_METHOD_SPERICAL
       ) As Object

    It is however easiest to use if you create a MapBasic project and include this module and a few others. Maybe that is taking this to a different level.

    Just thought I would mention it.

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 10.  RE: Trying to draw a shape being line, arc, line

    Posted 09-19-2022 03:41
    Edited by Peter Møller 09-19-2022 08:22
    Hello,

    Always up for a challenge...

    I create a mbp file :

    [Link]
    Application=Sector_v3.mbx
    Module=Sector_v3.mbo
    Module=.\..\mbLibrary-master\OBJLib.MBO

    I compiled your module OBJLib as MBO. Got rid of the ERRCreate statement, not why it doesn't like it.
    and created another MBO file to call your function and link all together.

    Declare Sub Main
    Declare Function OBJCreateAnnulus( ByVal oCenter As Object
       , ByVal fDirection As Float
       , ByVal fRadiusInner As Float 'meters
       , ByVal fRadiusOuter As Float 'meters
       , ByVal fAngleWidth As Float
       , ByVal nResolution As Integer
       , ByVal nCalculationMethod As Integer 'CALC_METHOD_CARTESIAN / CALC_METHOD_SPERICAL
       ) As Object


    '******************************************

    Sub Main

    Set CoordSys Table Live_Cell
    Update Live_Cell
    Set OBJ = OBJCreateAnnulus(CreatePoint(actual_longitude, actual_latitude), Azimuth, 0, Radius, Beamwidth, 120, 1 )

    End Sub

    '*******************************

    Got the mbx and run it, but not getting much.

    Questions:
    ByVal nCalculationMethod As Integer 'CALC_METHOD_CARTESIAN / CALC_METHOD_SPERICAL
    That's define as integer, so is it 0 or a 1 ?

    In the previous case, we had to rotate by 90deg. Is it required here also or not? I can't see any ajustements in your module.

    Best regards
    Alban





    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 11.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-19-2022 08:34
    Hi Alban

    You would need to include some more modules if you wanted to use the ERRCreate statement.

    The project file would probably need to also include ERRORLib and DEBUGLib.
    And your module Sector_v3.mb would also have to include those modules.

    Here are the defines of the two calculation methods from the file OBJLib.def:
    Define CALC_METHOD_CARTESIAN 1
    Define CALC_METHOD_SPERICAL 2

    You would still need to convert your Azimuth using the function MathNorth2MathAngle
    And you want to use the spherical calculation method (2)

    Your statement would look like this:

    Set CoordSys Table Live_Cell
    Update Live_Cell
      Set OBJ = OBJCreateAnnulus(CreatePoint(actual_longitude, actual_latitude), MathNorth2MathAngle(Azimuth), 0, Radius, Beamwidth, 120, 2)

    If your records have a point where the center of the sectors is, you can also refer to that instead:
    Set CoordSys Table Live_Cell
    Update Live_Cell
      Set OBJ = OBJCreateAnnulus(OBJ, MathNorth2MathAngle(Azimuth), 0, Radius, Beamwidth, 120, 2)

    Hopefully, this helped. If not, try to share your sourcecode and if possible a table with just a few records.


    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 12.  RE: Trying to draw a shape being line, arc, line

    Posted 09-20-2022 04:24
    Hello,

    works perfectly.
    Thanks a lot for your help.

    Is there a documentation somewhere about those librairies?

    thanks

    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 13.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-22-2022 01:40
    Hi Alban,

    No, sorry, the documentation is the libraries themselves, unfortunately.
    Maybe I should create a small document describing the functions and how to use them

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 14.  RE: Trying to draw a shape being line, arc, line

    Posted 09-25-2022 23:02
    Hello Peter,

    I noticed a small issue....
    The sectors created are Regions, so I converted those to lines so it is more visible as we have many sectors in our sites. Now, the issue I have is about labelling..

    As the sector is created via a circle and a polyline, when adding labels, the labels will go on the edge of the sector, i.e on the first segment creating the circle instead of having the label like below:


    Is there a way to do this when using the CreateAnnulus function?
    Thanks

    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 15.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-26-2022 03:30
    Hi Alban

    I think your problem originates from you converting the polygons to polylines.

    I can see a problem in seeing through all those many polygons as they overlap. This is especially difficult if the polygons have a fill. I would suggest keeping your sectors as polygons but changing the way they are styled. For polygons, you can specify that they should have no fill and so look more like lines.

    It does seem as if your sectors have different colors. Have you applied a thematic on the layer based on their type?

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 16.  RE: Trying to draw a shape being line, arc, line

    Posted 09-26-2022 03:39

    Hello Peter,

    Thanks for the reply.
    Indeed, I also tried to change the style and yes it works... however the problem is about labelling. As it is a region, the label is basically set in the centroid while I'd like to have like on the screnshoot. Not sure if that's possible then.



    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 17.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-26-2022 04:19
    Ah, sorry, I misunderstood your problem.

    To get to that labeling you are looking for, you will have to convert the sectors to polylines. You can do this in two ways:

    1. Save a copy of your table and change all the objects to polylines. In this way, you will still have your polygons and now also a copy where they are represented as polylines.

    2. Run a query that converts the polygons into polylines:
    Select s.*, ConvertToPline(s.obj) object
    From sectors As "s"
    Into Sectors_As_Polylines

    You will need MapInfo Pro v2019 or later to be able to run this query and you will have to run it through the SQL Window.
    You can now add the resulting query to your map, and use this for labeling. 

    To save the query, you will have to save it as a workspace so sometimes this might not work.

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 18.  RE: Trying to draw a shape being line, arc, line

    Posted 09-26-2022 22:26
    Hello Peter,

    Thanks. With the query I am still getting the same thing:
    Region are still there. If i click in a region then click on convert and polyline then it will convert.
    I am using V21.1.



    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 19.  RE: Trying to draw a shape being line, arc, line

    Employee
    Posted 09-27-2022 01:22
    Hi Alban

    You are missing a single but very important keyword in your query: ConvertToPline(s.obj) object

    The keyword object after a spatial expression tells MapInfo Pro to use the object returned by the spatial expression as the object for the query.

    Let me know if that helps

    ------------------------------
    Peter Horsbøll Møller
    Principal Presales Consultant | Distinguished Engineer
    Precisely | Trust in Data
    ------------------------------



  • 20.  RE: Trying to draw a shape being line, arc, line

    Posted 09-27-2022 22:33
    Hello Peter,

    Good pick up.
    Works fine now.
    Thanks for your help!


    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------



  • 21.  RE: Trying to draw a shape being line, arc, line

    Posted 09-19-2022 03:34
    Hello Peter,

    Thanks a lot.
    There was a small typo, but that's ok :)
    That's very fast now! The loop stuff was the problem as you indicated earlier.

    Best regards
    Alban

    ------------------------------
    Alban Spella-Barberet
    NBN Co Limited
    North Sydney NSW
    ------------------------------