CEXT-Dan / PyRx

Python for AutoCAD
43 stars 7 forks source link

BCAD V24 crashes with GeoCoordinateSystem #14

Closed schoeller closed 5 months ago

schoeller commented 6 months ago

Dear all,

already known from this forum post I hereby document the behaviour.

I am running BCAD V24 with Python 3.12.2 and PyRx 1.2.003.20240314.

When calling subsequent script as per this post all works well.

import traceback
from pyrx_imp import Rx
from pyrx_imp import Ge
from pyrx_imp import Gi
from pyrx_imp import Gs
from pyrx_imp import Db
from pyrx_imp import Ap
from pyrx_imp import Ed
from pyrx_imp import Cv
import math

import requests
import pandas as pd
import geopandas as gpd

print("added command - AddTin")
print("added command - addreferencepoints")

# debug
def PyRxCmd_pydebug() -> None:
    import PyRxDebug
    PyRxDebug.startListener()

def getGeoDataId(db: Db.Database) -> Db.ObjectId:
    if not Db.Core.hasGeoData(db):
        data = Db.GeoData()
        data.setBlockTableRecordId(db.modelSpaceId())
        return data.postToDb()
    return Db.Core.getGeoDataObjId(db)

def makeGeoDataFrame() -> gpd.GeoDataFrame:
    url = "https://overpass-api.de/api/interpreter"

    query = """
        [out:json];
        area(id:3600062650)->.dt;
        (
            node["triangulation_point"](area.dt);
            node["survey_point"](area.dt);
            node["man_made"="survey_point"](area.dt);
        );
        out geom;
    """ 
    response = requests.get(url, params={"data": query})
    data = response.json()
    return gpd.GeoDataFrame(data["elements"])

def PyRxCmd_AddTin():
    try:
        db = Db.curDb()
        geoDataId = getGeoDataId(db)
        if geoDataId.isNull():
            return
        geoData = Db.GeoData(geoDataId, Db.OpenMode.kForWrite)
        geoData.setCoordinateSystem("WORLD-MERCATOR")
        gdf = makeGeoDataFrame()

        elev = 0.0  # how?
        pnts = []
        for index, row in gdf.iterrows():
            pnts.append(geoData.transformFromLonLatAlt(Ge.Point3d(row.lat, row.lon, elev)))
            #pnts.append(geoData.transformToLonLatAlt(Ge.Point3d(row.lat, row.lon, elev)))

        extents = Db.Extents()
        extents.addPoints(pnts)
        surf = Cv.CvDbTinSurface()
        surf.setDatabaseDefaults(db)
        surf.initialize(extents.minPoint(), extents.maxPoint(), len(pnts))
        surf.addPoints(pnts)
        db.addToModelspace(surf)

    except Exception as err:
        traceback.print_exception(err)

def PyRxCmd_addreferencepoints():
    try:
        gdf = gdf = makeGeoDataFrame()
        db = Db.HostApplicationServices().workingDatabase()
        model = Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.kForWrite)
        geoDataId = getGeoDataId(db)
        if geoDataId.isNull():
            return
        geoData = Db.GeoData(geoDataId, Db.OpenMode.kForWrite)
        geoData.setCoordinateSystem("WORLD-MERCATOR")

        for index, row in gdf.iterrows():
            cpoint = Cv.CvDbPoint()
            cpoint.setDatabaseDefaults()
            cpoint.setNumber(index)
            cpoint.setEasting(row.lat)
            cpoint.setNorthing(row.lon)
            cpoint.setElevation(0)
            cpoint.setName(str(row.tags))

            #transform?
            tp = geoData.transformFromLonLatAlt(Ge.Point3d(row.lat,row.lon,0))
            #tp = geoData.transformToLonLatAlt(Ge.Point3d(row.lat,row.lon,0))
            cpoint.setPosition(tp)

            model.appendAcDbEntity(cpoint)

    except Exception as err:
        traceback.print_exception(err)

When calling the script as per this post, BCAD crashes without notice.

import traceback
from pyrx_imp import Rx
from pyrx_imp import Ge
from pyrx_imp import Gi
from pyrx_imp import Gs
from pyrx_imp import Db
from pyrx_imp import Ap
from pyrx_imp import Ed
#from pyrx_imp import Cv

# debug
def PyRxCmd_pydebug() -> None:
    import PyRxDebug
    PyRxDebug.startListener()

def getGeoDataId(db: Db.Database) -> Db.ObjectId:
    if not Db.Core.hasGeoData(db):
        data = Db.GeoData()
        data.setBlockTableRecordId(db.modelSpaceId())
        return data.postToDb()
    return Db.Core.getGeoDataObjId(db)

def PyRxCmd_doit() -> None:
    try:

        db = Db.curDb()
        geoCS = Db.GeoCoordinateSystem.create("UTM84-43N")
        xmlStr = geoCS.getXmlRepresentation()
        print(geoCS.getEpsgCode())

        geoDataId = getGeoDataId(db)
        if geoDataId.isNull():
            return

        geoData = Db.GeoData(geoDataId, Db.OpenMode.kForWrite)
        geoData.setCoordinateSystem(xmlStr)
        geoData.setCoordinateType(Db.GeoTypeOfCoordinates.kCoordTypLocal)
        geoData.setHorizontalUnits(Db.kUnitsMillimeters)
        geoData.setVerticalUnits(Db.kUnitsMillimeters)
        geoData.setDesignPoint(Ge.Point3d.kOrigin)
        geoData.setUpDirection(Ge.Vector3d.kZAxis)
        refPtInLatLong = Ge.Point3d(78.384402, 17.434586, 0.0)
        refPtInUTM84 = geoData.transformFromLonLatAlt(refPtInLatLong)
        geoData.setReferencePoint(refPtInUTM84)
        geoData.setNorthDirectionVector(Ge.Vector2d.kYAxis)

    except Exception as err:
        traceback.print_exception(err)
CEXT-Dan commented 6 months ago

Hi, I have reported the issue with Bricsys (SR-174110)

schoeller commented 5 months ago

It happens when calling

xmlStr = geoCS.getXmlRepresentation()

may related to a missing coordinate-system database file?

schoeller commented 5 months ago

It happens when calling

xmlStr = geoCS.getXmlRepresentation()

may related to a missing coordinate-system database file?

Explosion seems to have been fixed in V24.2.04.

Success module GEOCODE is loaded: 
: DOIT
32643

Transformation still coherent with your posting

CEXT-Dan commented 5 months ago

Apparently, there’s something wrong with my transformation in that my coordinates are too close to the poles I probably missed setting up a unit or something. I don’t know enough about this topic. Bricsys had replied that they were going to fix the Z issue