Processing semantics (attributes) of objects in python

Print Previous page Top page Next page

The semantics of an object consists of a set of characteristics that have a numeric code, key (field name), name, value type. The value of semantics can be selected from a list, contain a link to a file, or be calculated dynamically (semantics of the formula type). If a semantic characteristic has the attribute "Allowed to be repeated", then an object can have several semantics with one code (and key).

 

To process some semantics, the user must specify its code. The code can be determined by the key (field name), selected from the list of classifier semantics, read from the object semantics by the serial number of the characteristic in the object semantics record. Different objects, even of the same layer and type, may have a different set of characteristics and their sequence in the semantics record.

 

A standard tkinter component can be used to select semantics from a list in a dialog.

 

def ConvertSemanticAltitude(hmap:maptype.HMAP, hobj:maptype.HOBJ) -> float: #caption:Пересчитать высоту в семантике в футы или метры

 

   root = tkinter.Tk()

   root.title("Пересчитать высоту в семантике")

 

   src_label = tkinter.Label(text="Входная семантика: ")

   out_label = tkinter.Label(text="Выходная семантика: ")

   src_label.grid(row=0, column=0, sticky="w")

   out_label.grid(row=1, column=0, sticky="w")

 

   src_value = tkinter.IntVar()

   out_value = tkinter.IntVar()

   src_entry = tkinter.Entry(width=10, textvariable=src_value)

   out_entry = tkinter.Entry(width=10, textvariable=out_value)

   src_entry.grid(row=0,column=1, padx=5, pady=5)

   out_entry.grid(row=1,column=1, padx=5, pady=5)

 

   semname = mapsyst.WTEXT(64)

   hrsc = rscapi.mapGetRscIdent(hmap, hmap)

   rscapi.mapGetRscSemanticNameUn(hrsc, 4, semname, semname.size())

   select_src = tkinter.Button(text=semname.string())

   select_out = tkinter.Button(text=semname.string())

   src_value.set(4)

   out_value.set(4)

 

   def SelectSemanticSrc():

       parm = maptype.TASKPARMEX()

       parm.Handle = mapapi.mapGetHandleForMessage()

       semcode = mapselec.selSemanticSelectInit(hrsc, ctypes.byref(parm), src_value.get())

       if semcode != 0:

           src_value.set(semcode)

           rscapi.mapGetRscSemanticNameUn(hrsc, semcode, semname, semname.size())

           select_src.configure(text=semname.string())

 

   def SelectSemanticOut():

       parm = maptype.TASKPARMEX()

       parm.Handle = mapapi.mapGetHandleForMessage()

       semcode = mapselec.selSemanticSelectInit(hrsc, ctypes.byref(parm), src_value.get())

       if semcode != 0:

           out_value.set(semcode)

           rscapi.mapGetRscSemanticNameUn(hrsc, semcode, semname, semname.size())

           select_out.configure(text=semname.string())

 

   select_src.configure(command=SelectSemanticSrc)

   select_src.grid(row=0, column=2, padx=10, sticky="w")

   select_out.configure(command=SelectSemanticOut)

   select_out.grid(row=1, column=2, padx=10, pady=2, sticky="w")

 

   type_value = tkinter.IntVar()

   type_value.set(1)

   met2feet = tkinter.Radiobutton(root, text="в футы", variable=type_value, value=1).grid(row=2, column=1, sticky="w")

   feet2met = tkinter.Radiobutton(root, text="в метры", variable=type_value, value=2).grid(row=2, column=2, sticky="w")

 

   ret_value = tkinter.IntVar()

   ret_value.set(0)

   multi_f = 1. / 0.3048

   multi_m = 0.3048

 

   def Run():

       type = type_value.get()

       if type == 2:

          multi = multi_m

       else:

          multi = multi_f

 

       ret = SemanticAltitudeToFeet(hmap, hobj, src_value.get(), out_value.get(), multi)

       ret_value.set(ret)

       root.destroy()

 

   def Close():

       root.destroy()

 

   message_button = tkinter.Button(text="Выполнить", command=Run)

   message_button.grid(row=3,column=1, padx=5, pady=5, sticky="e")

   message_button = tkinter.Button(text="Отменить", command=Close)

   message_button.grid(row=3,column=2, padx=5, pady=5, sticky="w")

 

   root.eval('tk::PlaceWindow . center')

   root.mainloop()

   return float(ret_value.get())

 

dialog_3

 

To work with the classifier, you need to get the HRSC identifier.

 

hrsc = rscapi.mapGetRscIdent(hmap, hmap)

 

To call standard GIS dialogs, you must declare the TASKPARMEX structure.

 

       parm = maptype.TASKPARMEX()

       parm.Handle = mapapi.mapGetHandleForMessage()

 

To select semantics from a list, you can use the mapselec.selSemanticSelectInit function.

 

       semcode = mapselec.selSemanticSelectInit(hrsc, ctypes.byref(parm), src_value.get())

 

dialog4_engl

 

 

The mapsyst.WTEXT class is used to send and receive UTF-16 (WCHAR/WCHAR2) encoded strings to and from the MAPAPI function. The class declaration specifies the size limit for the string buffer.

 

   semname = mapsyst.WTEXT(64)

 

Into MAPAPI functions that return a value as a string the name of the class variable and the size of the buffer are passed.

 

   rscapi.mapGetRscSemanticNameUn(hrsc, semcode, semname, semname.size())

 

The resulting string can be used as a python string using the string() method.

 

   select_out.configure(text=semname.string())

 

Having received the codes of processed semantics, you can process the corresponding fields in the record using MAPAPI functions.

 

# Convert object altitude to feet or meters

def ObjectAltitudeToFeet(hobj:maptype.HOBJ, srccode, outcode, multi) -> int:

   if hobj == 0:

      return 0

   srcnumber = mapapi.mapSemanticCodeValuePro(hobj, srccode, None, 0, 1, 0)

   if srcnumber == 0:

      return 0

   value = mapapi.mapSemanticCodeDoubleValue(hobj, srccode, 1)

   value = value * multi

   if srccode == outcode:

      return mapapi.mapSetSemanticDoubleValue(hobj, srcnumber, value)

   else:

      outnumber = mapapi.mapSemanticCodeValuePro(hobj, outcode, None, 0, 1, 0)

      if outnumber > 0:

         return mapapi.mapSetSemanticDoubleValue(hobj, outnumber, value)

      else:

         return mapapi.mapAppendSemanticDouble(hobj, outcode, value)

 

To search for a characteristic that has a given code, you can use the mapapi.mapSemanticCodeValuePro function.

 

   srcnumber = mapapi.mapSemanticCodeValuePro(hobj, srccode, None, 0, 1, 0)

 

If the semantic value is planned to be processed in symbolic form, then the request may look like:

 

   semvalue = mapsyst.WTEXT(1024)

   srcnumber = mapapi.mapSemanticCodeValuePro(hobj, srccode, semvalue, semvalue.size(), 1, 0)

 

If a repeatable value of semantics is expected, then after the string buffer size field in bytes, the sequence number is indicated, the request may look like:

 

   srcnumber = mapapi.mapSemanticCodeValuePro(hobj, srccode, semvalue, semvalue.size(), number, 0)

   number += 1

 

The semantic value can be requested in numerical form (Long or Double) by code, taking into account the repeated value.

 

   value = mapapi.mapSemanticCodeDoubleValue(hobj, srccode, 1)

 

The request to read the value by the characteristic number in the semantics record will be executed faster.

 

   value = mapSemanticDoubleValue(hobj, srcnumber)

 

A new characteristic value can be written to an existing characteristic or added to the object's semantics.

 

   outnumber = mapapi.mapSemanticCodeValuePro(hobj, outcode, None, 0, 1, 0)

   if outnumber > 0:

       return mapapi.mapSetSemanticDoubleValue(hobj, outnumber, value)

   else:

       return mapapi.mapAppendSemanticDouble(hobj, outcode, value)

 

f the added characteristic does not have the "Allowed to be repeated" attribute, then the second value will replace the first one automatically and the mapapi.mapAppendSemantic function will work as mapapi.mapSetSemantic. After editing the semantics, the order of the fields may change. In some cases, the field being updated is removed and written to the end with the new value.