User:Chilin/mp2nm2

From OpenStreetMap Wiki
Jump to navigation Jump to search

MP -> NM2

Скрипт на VBScript для автоматизации процесса конвертирования из формата .mp в формат .nm2 и генерации протокола ошибок.
Внимание! Генерация протокола ошибок возможна только при использовании зарегистрированной версии gpsmapedt

'mp2nm2.vbs
'Based on open source code published by (c) Konstantin Galichsky, http://www.geopainting.com
'
'Developers: 
'	Konstantin Galichsky (kg@geopainting.com)
'	Chilin (chilin dog rambler dot ru)
'
'This script uses GPSMapEdit to verify and convert map to NM2 format.
'Save report as HTML file for OpenStreetMap project.
'
'Usage: mp2nm2.vbs [-noVerify/-onlyVerify] <file.mp>
'	Without Key - verify & convert map
'	-noVerify   - only convert to NM2
'	-onlyVerify - only verify map
'
Option Explicit
Dim WS,fso,log, logPath
Set fso = CreateObject ("Scripting.FileSystemObject")
Set WS  = WScript.CreateObject("WScript.Shell")

logPath = fso.GetAbsolutePathName(WScript.ScriptFullName + "\..\") +"\"+ fso.GetBaseName(WScript.ScriptName)+".log"
if fso.FileExists(logPath) then
	set log = fso.OpenTextFile(logPath,8)
else
	Set log = fso.CreateTextFile (logPath)
end if

call LogMsg("Starting script "&WScript.ScriptName)

dim mapName,scrKey
Select Case WScript.Arguments.Count
	Case 1
		scrKey = ""
		mpName = WScript.Arguments(0)
	Case 2
		scrKey = UCase( WScript.Arguments(0))
		mpName = WScript.Arguments(1)
		if not (scrKey = "-NOVERIFY" or scrKey = "-ONLYVERIFY") then
			call ErrMSG("Script called with wrong parameter. Use key: ''-noVerify'' or ''-onlyVerify''")
		end if
	Case else
		call ErrMSG("Script called without the required parameter. Please, use: "&WScript.ScriptName&" [-noVerify/-onlyVerify] <file.mp>")
End Select

Dim mapPath,mpName,mapFolder
mapFolder = fso.GetAbsolutePathName (mpName + "\..\") + "\"
mapPath   = fso.GetAbsolutePathName(mpName)
mapName   = LCase (fso.GetBaseName (mapPath))

if not fso.FileExists(mapPath) Then
	call ErrMSG("File ''"&mpName&"'' does't exist")
end if

'Check type of verify
'	536870911 - Check all error
'	268435456+... - Detailed verify 
'	+1  - Check polygons for self-interselection
'	+2  - Check routable polylines for self-interselection in nodes
'	+4  - Find misaligned/duplicated nodes
'	+8  - Check polygons for overlapping
'	+16 - Find to close nodes
'	+32 - Check routable roads roundabouts for way-1 
'	+64 - Not used (reserved) 
'	+128 - Check Road DeadEnds
'Warning - +4 is critical error for nm2 format
Const CriticalError = "Duplicated nodes"
Dim DetailedVerify, tmpNavitel
DetailedVerify = 268435456+4+1+2+16+32

'Connect to GPSMapEdit
On Error Resume Next
Err.Clear
Dim GME,GMEVersion
Set GME = CreateObject ("GPSMapEdit.Application.1")

'Check connect and check version of GPSMapEdit
GMEVersion = GME.Version
if err.number <> 0 then
	GME.Exit
	call ErrMSG("Internal error: "&err.number&" - "&err.description)
end if
On Error GoTo 0
If GMEVersion < "1.0.61.4" Then
	GME.Exit
	call ErrMSG("Obsolete version of GPSMapEdit is used. Current version: "&GMEVersion&", please upgrade to 1.0.61.4 or higher.")
End If
GME.MinimizeWindow

'Open map in GPSMapEdit
GME.Open mapPath, False

	tmpNavitel = -1
if scrKey <> "-NOVERIFY" then
	'Connect to GPSMapEdit.IEdit /only registered version GPSMapEdit/
	Dim pEdit
	Set pEdit = GME.Edit
	If pEdit Is Nothing Then
		GME.Exit
		call ErrMSG("IEdit may be used only registered version GPSMapEdit")
	End If

	'Verifing Map
	lReportLines = pEdit.VerifyMap (DetailedVerify, strReport)
	call LogMsg("Verified file "&mapPath &" - "& lReportLines & " errors.")
	'Spliting report lines into array
	dimReport = Split(strReport,vbCrLf)

	Dim lReportLines,nReportLines,strReport,dimReport,dicReport
	Dim strLine,strCoo,GMEErr,nGMEErr,nPoint,dPoint,arrGMEe()
	Set dicReport  = CreateObject("Scripting.Dictionary")

	'Parsing report lines
	ReDim arrGMEe(1)
	nGMEErr    = 0
	nPoint     = 0
	dPoint     = 0
	If lReportLines > 0 Then
		for nReportLines = 1 to lReportLines
			strLine = dimReport(nReportLines)
			strCoo = Split(strLine,",")(0)+"&mlon="+Split(strLine,",")(1)
			GMEErr = MID(Split(strLine,",")(3),2,Len(Split(strLine,",")(3))-2)
			If Not dicReport.Exists(strCoo) Then
				dicReport.Add strCoo,GMEErr
				nPoint = nPoint + 1
			else
				if GMEErr = CriticalError then
					dicReport.Item(strCoo) = CriticalError
				end if
				dPoint = dPoint + 1
			End If
			if IsInDim(arrGMEe,GMEErr) = -1 Then
				arrGMEe(nGMEErr) = GMEErr
				nGMEErr = nGMEErr + 1
				ReDim Preserve arrGMEe(nGMEErr)
			End if
		Next
		call LogMsg("Parsing complited. Error lines: "&lReportLines&". Types of error: "&nGMEErr&". Real error point: "&nPoint&". Double error point: "&dPoint)
		'Up critical error in array
		tmpNavitel = IsInDim(arrGMEe,CriticalError)
		if  tmpNavitel > -1 then
			arrGMEe(tmpNavitel) = arrGMEe(0)
			arrGMEe(0) = CriticalError
			call LogMsg(".nm2 does't exported. See html File.")
		end if
	End If
End if

'Export to nm2
if scrKey ="-NOVERIFY" or scrKey = "" then
	if tmpNavitel = -1 then
		dim nm2Path
		nm2Path = mapFolder+mapName+".nm2" 
		On Error Resume Next
		Err.Clear
		GME.SaveAs nm2Path, "navitel-nm2"
		On Error GoTo 0
		if fso.FileExists(nm2Path) then
			call LogMsg("Exported file: "&nm2Path)
		else
			call LogMsg("File: "&nm2Path&" does't exported. Use VerifyMap.")
		end if
	End If
End if
GME.Exit

if scrKey <> "-NOVERIFY" then
	'Export to HTML
	if nPoint <> 0 then
	Dim fHtml,nErr,i1,i2,htmlPath
	htmlPath  = mapFolder+mapName+".html"
	Set fHtml = fso.CreateTextFile(htmlPath, true)

	fHtml.WriteLine strConv("<body><head><meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/><title>"&mapName&": Картографические ошибки</title></head><CENTER><h2>Протокол проверки данных OpenStreetMap</h2></CENTER>","windows-1251","utf-8")

		fHtml.WriteLine strConv("Ниже, перечислены ссылки на картографические ошибки, обнаруженные при конвертации данных OpenStreetMap в формат Навител (.nm2).<br>Вы можете помочь проекту исправив их.<br>","windows-1251","utf-8")
	
	if tmpNavitel <> -1 then
		fHtml.WriteLine strConv("<b>Обратите внимание!</b> Ошибка <b><FONT bold='yes' font='1' color='FA8072'>'Duplicated nodes'</font></b>, является крититической. Автоматическая конвертация невозможна, если её не исправить. Таким образом, если Вы обнаружите, что область на главной странице не обновляется - исправьте  эти ошибки, и в следующий раз актуальная карта станет доступна для загрузки.","windows-1251","utf-8")
	end if
	fHtml.WriteLine "<div align='center'><table width='100%' border=1 cellspacing=0 cellpadding=0 align=center>"
	if dicReport.Count > 0 then
		for i1 = 0 to UBound(arrGMEe)-1
			NErr = 0
			For Each i2 In dicReport
				if arrGMEe(i1) = dicReport.Item(i2) then
					NErr = NErr + 1
					if NErr = 1 then
						if arrGMEe(i1) = CriticalError then
							fHtml.WriteLine "<tr><th><p style='background:#FA8072'>"&arrGMEe(i1)&"</p></th></tr><tr><td>"
						else
							fHtml.WriteLine "<tr><th>"&arrGMEe(i1)&"</th></tr><tr><td>"
						end if
					end if
					fHtml.WriteLine "<a href=http://osm.org/?mlat=" & i2 & "&zoom=18 target='_blank'>" & NErr & "</a>"
				end if
			next
		next
	end if
	fHtml.WriteLine strConv("</td></tr></table></div>Карта: "&mapName&".mp<br>Последняя проверка: "&Now()&"<br/>Всего ошибок: "&nPoint&"</br></br><a href='javascript:window.history.back();'>Назад</a></body>","windows-1251","utf-8")
	fHtml.Close
	call LogMsg("Exported file: "&htmlPath)
	end if
End if

call LogMsg("End of script.")
log.Close
'WS.Run "%comspec% /c echo " & Chr(7), 0, True
WScript.Quit (0)

Function IsInDim(Arr,Var)
	IsInDim = -1
	Dim i
	For i = LBound(Arr) To UBound(Arr)
		if Arr(i) = Var then 
			IsInDim = i
			Exit For
		end if
	next
End Function

Sub ErrMSG(Text)
	call LogMsg("Error: "&Text)
	call LogMsg("Script halted")
	WScript.Quit(1)
End Sub

Sub LogMsg(Text)
	log.WriteLine now()&": "&Text
End Sub

Function StrConv(Text,SourceCharset,DestCharset)
	dim Stream
	Set Stream      = CreateObject("ADODB.Stream")
	Stream.Type     = 2
	Stream.Mode     = 3
	Stream.Open
	Stream.Charset  = DestCharset
	Stream.WriteText Text
	Stream.Position = 0
	Stream.Charset  = SourceCharset
	StrConv         = mid(Stream.ReadText,4)
End Function