KLIC-tool en AutoCAD

Jul 8th, 2010 | Posted by Anton | Filed under VB
Belangstelling voor de KLIC tool? En nog gratis ook? Kijk hier voor meer informatie en om de tool echt gratis aan te vragen. Voor vergelijkbare producten zoals InfraCad en WION-Cad betaal je al snel 300 euro per jaar. Beetje jammer van het geld toch?

Degene die weleens oriëntatiemeldingen deed bij de KLIC weet intussen dat de levering van kabels- en leidingendata niet meer rechtstreeks van de leverancier komt, maar van het Kadaster, in het kader van de wet WION (Wet informatie-uitwisseling ondergrondse netten). En dan is ook intussen wel bekend dat de data wordt aangeleverd in PNG bestanden, bitmaps. Helaas geen DWG's, geen PDF's, maar gelukkig ook geen Word-bestanden meer waarin een schermafdruk van een rioolnet is geplaatst.

Toch is PNG ook niet alles. Plak ze in AutoCAD en dankzij de grove korrel steekt het behoorlijk af met de scherpe lijnen van de GBK. En dan is het nog de vraag hoe je die PNG's keurig ingepast krijgt op de ondergrond.

Je zou toch zeggen dat je er op vooruit zou moeten gaan als "men de krachten bundelt en data uniform aan gaat leveren"? Maar helaas, data is geld waard en dus gaan we het niet zomaar weggeven, wordt gedacht. Dus niet als mooie strakke vectoren, niet met GML, geen administratieve data, want stel je voor! Dus wordt alles geleverd in kale bitmaps zonder enige relatie of administratieve coderingen. Zelfs de maatvoering wordt als bitmap geleverd.

Dus we nemen het maar voor lief dat de data als bitmap wordt aangeleverd en dat we niet beter krijgen dan dat. Maar krijgen we het nog gemakkelijk in AutoCAD? Gelukkig wel.

Het leek me een mooie taak om te proberen om met VB.NET een programma te maken die de afbeeldingen van de KLIC levering in AutoCAD plaatst. Hoe moeilijk kan dat nou zijn! Een afbeelding is slechts een object met eigenschappen dus dat leek gemakkelijk. Ook het plaatsen op de juiste locatie leek niet moeilijk. Wie wel eens een levering van het Kadaster doorgespit heeft, weet dat er een XML-bestand geleverd wordt met daarin enkele handige data. O.a. de RD-coördinaten.


<ns3:Envelope srsName="<strong>epsg:28992</strong>" srsDimension="<strong>2</strong>" axisLabels="<strong>x y z</strong>" uomLabels="<strong>m m m</strong>">
  <ns3:lowerCorner>191703 401494</ns3:lowerCorner>
  <ns3:upperCorner>191801 401585</ns3:upperCorner>
</ns3:Envelope>

Hierboven zien we de RD-coördinaten. Verder is te zien dat alle PNG's die beginnen met LG de leidinggegevens bevatten, die met MV de maatvoering en die met AN de beschrijvende teksten. In de XML wordt overigens nog beschreven wie levert en wat geleverd wordt. Dus alles is voorhanden.

Het schrijven van de KLIC-tool begint dus relatief eenvoudig. Begin met een OpenFileDialog om een XML-bestand te selecteren, lees de XML uit en haal de coördinaten eruit, blader dan door de map op zoek naar de PNG's en plaats deze in AutoCAD.

Helaas bleek het niet zo eenvoudig. Het plaatsen van een afbeelding met DotNet in AutoCAD is vrij omslachtig. Het zijn geen standaard objecten. Eerst dient een Dictionary aangemaakt te worden waarin alle verwijzingen naar afbeeldingen worden opgeslagen. Dan moet de afbeelding aan die Dictionary worden toegevoegd, vervolgens moet de afbeelding als object in AutoCAD geplaatst worden, vervolgens moet het ObjectID naar de afbeeldingdefinitie worden verwezen en tenslotte nog geassocieerd worden. Er was bar weinig over te vinden op het internet. Gelukkig net voldoende informatie van Tony Tanzillo die een functie had geschreven. Alleen werkte deze niet helemaal naar behoren. Vervolgens wat discussies gehad op TheSwamp.org waar gelukkig hele deskundige nerds rondhangen en me de laatste zetjes in de goede richting hebben gegeven. En zodoende had ik tenslotte een goed werkende functie. En die je kunt hergebruiken. En dat is dan weer de kracht van DotNet.

Public Function Add_Raster(ByRef ThisDoc As Document, ByVal RasterFile As String, ByVal InsPoint As Geometry.Point3d, ByVal Scale As Double) As RasterImage
    Dim RasterEnt As RasterImage, RasterDef As RasterImageDef
    Dim ImageDicID, ImageDefID As ObjectId, ImageDic As DBDictionary
    Dim Matrix As Geometry.Matrix3d
    Dim btr As BlockTableRecord
    Dim RasterName As String = ""

    RasterName = RasterFile.Substring(RasterFile.LastIndexOf("\") + 1)
    RasterName = RasterName.Substring(0, RasterName.IndexOf("."))

    Add_Raster = Nothing
    If ThisDoc Is Nothing Then Exit Function

    Try

      Using Trans As Transaction = ThisDoc.TransactionManager.StartTransaction()

        RasterEnt = New RasterImage
        RasterEnt.Dispose() ' force loading of RasterImage.dbx module (needed for 2009 and earlier)

        RasterDef = New RasterImageDef
        RasterDef.SourceFileName = RasterFile
        RasterDef.ActiveFileName = RasterFile
        RasterDef.Load()

        ImageDicID = RasterImageDef.GetImageDictionary(ThisDoc.Database)
        If ImageDicID.IsNull Then
          RasterImageDef.CreateImageDictionary(ThisDoc.Database)
          ImageDicID = RasterImageDef.GetImageDictionary(ThisDoc.Database)
        End If
        If ImageDicID.IsNull Then
          MsgBox("Could not create image dictionary", MsgBoxStyle.Critical, "Failed")
          'Exit Try
        End If
        ImageDic = Trans.GetObject(ImageDicID, DatabaseServices.OpenMode.ForWrite)
        If ImageDic Is Nothing Then
          MsgBox("Could not open image dictionary", MsgBoxStyle.Critical, "Failed")
        Else
          If ImageDic.Contains(RasterName) Then
            MsgBox("That image name is already in use", MsgBoxStyle.Critical, "Failed")
          Else
            ImageDic.UpgradeOpen()
            ImageDefID = ImageDic.SetAt(RasterName, RasterDef)
            Trans.AddNewlyCreatedDBObject(RasterDef, True)
            RasterEnt = New RasterImage
            RasterEnt.SetDatabaseDefaults(ThisDoc.Database)
            Matrix = New Geometry.Matrix3d
            Matrix = Geometry.Matrix3d.Scaling(Scale / RasterDef.Size.X, New Geometry.Point3d(0, 0, 0))
            RasterEnt.TransformBy(Matrix)
            Matrix = Geometry.Matrix3d.Displacement(New Geometry.Vector3d(InsPoint.X, InsPoint.Y, InsPoint.Z))
            RasterEnt.TransformBy(Matrix)
            RasterEnt.ImageDefId = ImageDefID
            btr = Trans.GetObject(ThisDoc.Database.CurrentSpaceId, DatabaseServices.OpenMode.ForWrite)
            btr.AppendEntity(RasterEnt)
            Trans.AddNewlyCreatedDBObject(RasterEnt, True)
            RasterEnt.AssociateRasterDef(RasterDef)
            Trans.Commit()
          End If
        End If

      End Using

      Add_Raster = RasterEnt

    Catch ex As Exception

      MsgBox("Error inserting image " & RasterName, MsgBoxStyle.Critical, "Failed." & ex.ToString)

    End Try

  End Function

Bovenstaande functie werkt prima om afbeeldingen in te voegen. En uit de XML hadden we het invoegpunt al en de schaal is eenvoudig uit te rekenen. Voila, de KLIC-tool was geboren.

In samenwerking met CivilCenter uit Apeldoorn is de KlicTool gratis te verkrijgen voor geïnteresseerden. Kijk hier voor meer informatie en om de tool gratis aan te vragen.

Een voorbeeldfilmpje van de werking:

No comments yet.