Jump to content

Recommended Posts

Posted

I was searching for a way to highlight zones (regions, provinces, counties, etc) on a map, and I don't need  super precise maps so I wrote this script, based on picking up black and white maps (2 colors BW .png or .gif tested) and filling them with colors, writing down a sqlite database to associate zones with names (and other data as well), and reuse the map and the DB to display data, in my example reading a simple .txt file.

It's all based on this thread  and this other thread.

MapFlooder_RyzvYGJgLJ_2.thumb.png.27c2231e4210ff3e07053ae900c936aa.png

So I have two modes:

  1. The Map "creation mode" : you provide a map image and you start to pick up colors, set "upper level" region/state, and by clicking on a region you fill it and you name it, and all the data are saved on a sqlite DB (auto-created)
  2. when you have the map image and a DB with the correct associations, you can switch the "mode" to "show" (as by .ini file) and the script tries to read a "datafile" showing the zone names listed in datafile.

The code:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=Icone\mapFlooder.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

;MAP Flooder
;(C) NSC 2021
#include <GUIConstants.au3>
#include <_GOLLOG.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>
#include <Misc.au3>
#include <GDIPlus.au3>
Opt("mousecoordmode", 2)

Global $prgname = "MAP Flooder", $ver = "V.0.7", $Buttoncolor = "0xFF00FF", $MPini = @ScriptDir & "\MapFlooder.ini", $btest
Global $dbfullpath, $dbtable, $dbFields, $mapfile, $FloodMode, $datafile
Global $HDC, $hBrush, $hGraphics, $obj_orig
Global $Pic1, $gui, $width, $height, $bColor, $realtimeCoords, $lastclickcoords, $inputSup, $zonecountNum,$labeltest

#Region program

Gollog(">>>>>> Start MAP Flooder " & $ver)

ctrlini()

Gui()

SQLiteDBcreate()

If $FloodMode = "createdb" Then
    Gollog("CreateDB Mode")
    DBFlooder()
Else
    Gollog("Show MAP mode")
    MapShow("show")
EndIf

Close()

#EndRegion program


#Region funcS

Func Gui()

    _GDIPlus_Startup()
    $Pic1 = _GDIPlus_BitmapCreateFromFile($mapfile)

    $width = _GDIPlus_ImageGetWidth($Pic1)
    $height = _GDIPlus_ImageGetHeight($Pic1)


    If $FloodMode = "createdb" Then
        $gui = GUICreate($prgname & " " & $ver, $width + 150, $height)

        $labelLoadedMap = GUICtrlCreateLabel("Loaded Map", $width + 10, 5)
        $labelLoadedMap2 = GUICtrlCreateLabel(_FileToFileName($mapfile), $width + 10, 25)

        $labeldim = GUICtrlCreateLabel("Width*Height", $width + 10, 45)
        $labeldim2 = GUICtrlCreateLabel($width & " * " & $height, $width + 10, 65)

        $lastclickcoordslabel = GUICtrlCreateLabel("Last Click Coords", $width + 10, 100)
        $lastclickcoords = GUICtrlCreateLabel("xx - xx", $width + 10, 120, 180, 20)

        $realtimeCoordslabel = GUICtrlCreateLabel("Real Time Coords", $width + 10, 140)
        $realtimeCoords = GUICtrlCreateLabel("Real Time Coords", $width + 10, 160, 80, 20)

        $SuPzonelabel = GUICtrlCreateLabel("Supzone (region-state)", $width + 10, 200)
        $inputSup = GUICtrlCreateInput("sup", $width + 10, 220, 80, 20)
        $bColor = GUICtrlCreateButton($Buttoncolor, $width + 10, 250, 130, 30)
        GUICtrlSetBkColor($bColor, $Buttoncolor)

        $zonecountlabel = GUICtrlCreateLabel("Done Zone Count:", $width + 10, 320, 100, 20)
        $zonecountNum = GUICtrlCreateLabel("x", $width + 10, 340, 100, 20)

        $btest = GUICtrlCreateButton("TEST MAP", $width + 10, 380, 130, 30)
        $labeltest = GUICtrlCreateLabel("", $width + 10, 420, 130, 30)
    Else

        $gui = GUICreate($prgname & " " & $ver, $width, $height)

    EndIf

    GUISetState()
    $HDC = _WinAPI_GetDC($gui)
    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($HDC)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $Pic1, 0, 0, $width, $height)

EndFunc   ;==>Gui

Func MapShow($showmode) ; reading a simple text file with zone names, searching for names in DB and fill the map using stored coordinates

    If $showmode = "show" Then
        Local $aLines = FileReadToArray($datafile)
        Local $iLineCount = @extended
    EndIf

    If $showmode = "test" Then $iLineCount = 1
    If @error Then
        MsgBox(48, "MapFlooder", "There was an error reading the data file. @error: " & @error) ;
        Gollog("There was an error reading the data file. @error: " & @error)
        Close()
    Else
        Gollog("start filling zones")
        _SQLite_Startup()
        _SQLite_Open($dbfullpath)         ; open Database with zone definitions
        Local $hQuery, $aRow
        For $i = 0 To $iLineCount - 1

            If $showmode = "show" Then
                _SQLite_Query(-1, "SELECT * FROM " & $dbtable & " where zone = '" & $aLines[$i] & "'  ORDER BY zone ASC;", $hQuery) ; the query
            EndIf
            If $showmode = "test" Then
                _SQLite_Query(-1, "SELECT * FROM " & $dbtable & " ORDER BY zone ASC;", $hQuery) ; the query
            EndIf
            While _SQLite_FetchData($hQuery, $aRow) = $SQLITE_OK
                $hBrush = DllCall("gdi32.dll", "long", "CreateSolidBrush", "int", $aRow[2]) ; fill color read from DB
                $obj_orig = DllCall("gdi32.dll", "int", "SelectObject", "int", $HDC, "int", $hBrush[0])
                DllCall("gdi32.dll", "int", "FloodFill", "int", $HDC, "int", $aRow[3], "int", $aRow[4], "int", 0x000000)
                If $showmode = "test" Then
                    GUICtrlSetData($labeltest,$aRow[0])
                    Sleep(200)
                    GUISetState()
                EndIf
            WEnd
            _SQLite_QueryFinalize($hQuery)

        Next

        _SQLite_Close()
        _SQLite_Shutdown()
    EndIf

    While 1
        $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd
EndFunc   ;==>MapShow

Func DBFlooder()
    $zonecount = 0
    While 1
        $mp = MouseGetPos()
        GUICtrlSetData($realtimeCoords, $mp[0] & " - " & $mp[1])
        $msg = GUIGetMsg()

        If $msg = $GUI_EVENT_CLOSE Then ExitLoop

        If $msg = $bColor Then colorP()

        If $msg = $btest Then MapShow("Test")

        If $mp[0] < $width And $mp[1] < $height And _IsPressed("01") And WinActive($gui) Then
            $mp = MouseGetPos()
            GUICtrlSetData($lastclickcoords, $mp[0] & " - " & $mp[1])

            $hBrush = DllCall("gdi32.dll", "long", "CreateSolidBrush", "int", $Buttoncolor) ; fill color ok
            $obj_orig = DllCall("gdi32.dll", "int", "SelectObject", "int", $HDC, "int", $hBrush[0])
            DllCall("gdi32.dll", "int", "FloodFill", "int", $HDC, "int", $mp[0], "int", $mp[1], "int", 0x000000)

            Local $Zone = InputBox("Map Floode", "Zone ?")

            If $Zone = "" Or @error = 1 Then ; when manage wrong click, possibility to repeat

                ; set 'temp' color to highlight the 'wrong' click
                $hBrush = DllCall("gdi32.dll", "long", "CreateSolidBrush", "int", 0x4ccfc6) ; fill color wrong
                $obj_orig = DllCall("gdi32.dll", "int", "SelectObject", "int", $HDC, "int", $hBrush[0])

                DllCall("gdi32.dll", "int", "FloodFill", "int", $HDC, "int", $mp[0], "int", $mp[1], "int", 0x000000)

                ; restore color

                $hBrush = DllCall("gdi32.dll", "long", "CreateSolidBrush", "int", $Buttoncolor) ; fill color ok
                $obj_orig = DllCall("gdi32.dll", "int", "SelectObject", "int", $HDC, "int", $hBrush[0])

            Else

                _SQLite_Startup()
                _SQLite_Open($dbfullpath) ; open Database

                Local $SupZone = GUICtrlRead($inputSup)
                Local $data = '"' & $Zone & '","' & $SupZone & '","' & $Buttoncolor & '",' & $mp[0] & "," & $mp[1]
                _SQLite_Exec(-1, "INSERT INTO " & $dbtable & "(" & $dbFields & ") VALUES (" & $data & ");")
                If @error = -1 Then
                    GOLLOG("Error insert record")
                    MsgBox(48, "Error", "insert record")
                EndIf
                $zonecount += 1
                GUICtrlSetData($zonecountNum, $zonecount)

                _SQLite_Close()
                _SQLite_Shutdown()

            EndIf
        EndIf
    WEnd
EndFunc   ;==>DBFlooder

Func Close()
    Gollog("<<<<<<< closing...")
    _WinAPI_ReleaseDC($gui, $HDC)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>Close

Func SQLiteDBcreate() ;complete path e filename

    If Not FileExists($dbfullpath) Then

        GOLLOG("perform SQLite DB creation")
        Local $dbfolder = _FileToFilePath($dbfullpath)
        ;Local $dbfile = _FileToFileName($dbfullpath)
        If Not FileExists($dbfolder) Then DirCreate($dbfolder)
        ; =====================>>>>> START SQL DLL
        _SQLite_Startup()

        _SQLite_Open($dbfullpath) ; open Database

        ; creating first table
        If _SQLite_Exec(-1, "CREATE TABLE " & $dbtable & " (" & $dbFields & ");") = $SQLITE_OK Then
            GOLLOG("DB table - " & $dbtable & " - creation ok")

        Else
            GOLLOG("Error creating DB table : " & @error)

        EndIf

        _SQLite_Close()
        _SQLite_Shutdown()

    Else
        Gollog("DB already exist")
    EndIf
EndFunc   ;==>SQLiteDBcreate

; #FUNCTION# ====================================================================================================================
; Name ..........:  _FileToFilePath
; Description ...:  Returns a folder path from a FQPN (Fully Qualified Path Name)
; Syntax ........:  _FileToFilePath($sPath)
; Parameters ....:  $sPath              - a string value.
; Return values .:  Success             - String
;                   Failure             - Empty string as returned from StringLeft()
; Author ........:  Sam Coates
; ===============================================================================================================================
Func _FileToFilePath($sPath)

    Local $sReturn = StringLeft($sPath, StringInStr($sPath, "\", 0, -1) - 1)
    Return ($sReturn)

EndFunc   ;==>_FileToFilePath

; #FUNCTION# ====================================================================================================================
; Name ..........:  _FileToFileName
; Description ...:  Returns a filename from a FQPN (Fully Qualified Path Name)
; Syntax ........:  _FileToFileName($sPath[, $bIncludeExtension = True])
; Parameters ....:  $sPath              - a string value.
;                   $bIncludeExtension  - [optional] a boolean value. Default is True.
; Return values .:  Success             - String
;                   Failure             - Empty string as returned from StringLeft()
; Author ........:  Sam Coates
; ===============================================================================================================================
Func _FileToFileName($sPath, $bIncludeExtension = True)

    Local $sReturn = StringTrimLeft($sPath, StringInStr($sPath, "\", 0, -1))
    If $bIncludeExtension = False Then $sReturn = StringLeft($sReturn, StringInStr($sReturn, ".", 0, -1) - 1)
    Return ($sReturn)

EndFunc   ;==>_FileToFileName

Func colorP() ; modified for BGR color

    GOLLOG("Color Picker")
    Local $color = _ChooseColor(2)
    If $color = -1 Then
        GOLLOG("no color selected")
    Else
        Local $sCr = Hex($color, 6)
        Local $RGB_Buttoncolor = '0x' & StringMid($sCr, 1, 2) & StringMid($sCr, 3, 2) & StringMid($sCr, 5, 2)
        GUICtrlSetBkColor($bColor, $RGB_Buttoncolor)
        ; BGR color
        $Buttoncolor = '0x' & StringMid($sCr, 5, 2) & StringMid($sCr, 3, 2) & StringMid($sCr, 1, 2)
        GUICtrlSetData($bColor, $Buttoncolor)
        GOLLOG("new color " & $Buttoncolor & " selected")
    EndIf

EndFunc   ;==>colorP

Func ctrlini()   ;ini read
    If FileExists($MPini) Then

        GOLLOG("found: " & $MPini)
        $mapfile = IniRead($MPini, "map", "mapfile", "")
        $datafile = IniRead($MPini, "map", "datafile", "")
        $dbfullpath = IniRead($MPini, "db", "dbfullpath", "")
        $dbtable = IniRead($MPini, "db", "dbtable", "")
        $dbFields = IniRead($MPini, "db", "dbfields", "")
        $FloodMode = IniRead($MPini, "mode", "mode", "")

    Else
        GOLLOG($MPini & " NOT found..")
        Close()

    EndIf
EndFunc   ;==>ctrlini

#EndRegion funcS

All the needed files plus some example (image maps and DBs)

Link to all demo files

To test, copy all in a single folder and adjust the mapflooder.ini, also you can add to you includes the _gollog.au3 (used for log, you can avoid it deleting all Gollog() lines)

 

 

 

 

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...