標籤:mapwingis
mapwingis是個免費的開源外掛程式,官網上的教程大多都是c#的。最近做的一個project是用的MFC,怎麼調用他的介面了,網上的資料比較少,大多數都只有說到怎麼顯示向量或者影像資料就結束了,但是這樣的話,一開啟圖片游標的預設狀態是放大,滑鼠左鍵單擊一下是當大,右鍵是縮小,拖動是選中放大,怎麼實現像他給的demo中點擊放大,或者縮小,平移按鈕切換滑鼠狀態來完成相應的操作,mapwingis這些操作都是封裝好了的,只是c++的調用介面沒有詳細說明(也可能是我沒在官網找到。。。),網上有說是版本問題,說低版本有提供介面修改,我安裝了幾個低版本的也沒有什麼變化,還是改變不了。。還行先記錄一下怎麼在MFC中使用mapwingis外掛程式,最後在說一下怎麼改變游標狀態。
1、在官網下載mapwingis的安裝程式http://mapwingis.codeplex.com/releases/view/541892,下載後直接預設安裝,最後不要改安裝路徑,我沒有測試改了後的情況。預設安裝完成後會在c盤出現這個目錄C:\dev\MapWinGIS,記住這個目錄,後面會用到的。
2、用vs2012(其他的版本應該也可以)建立一個單文檔或者多文檔程式,接著在這個位置點擊建立一個類
然後在這個位置選擇添加activex控制項的類
3、 stdafx.h檔案中添加
#import "C:\dev\MapWinGIS\MapWinGIS.ocx" rename_namespace("mapWindow") rename("GetObject", "GISGetObject")
Resource.h中添加
#define IDC_MAP140
只有保證ID不重複即可
4、在視圖類添加一個變數
CDMap m_Map;這個CDMap類是之前置入activex類的時候產生的。我是直接用公有的變數,不安全?暫時還沒遇到。。
5、添加視圖類的WM_CREATE訊息的響應函數,動態建立地圖視窗,具體代碼如下:
int CXXView::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CView::OnCreate(lpCreateStruct) == -1)return -1;// TODO: 在此添加您專用的建立代碼CRect rect;GetClientRect(&rect);m_Map.Create(NULL,WS_CHILD | WS_VISIBLE | WS_BORDER,rect,this,IDC_MAP);return 0;}
6、添加視圖類的WM_SIZE訊息的響應函數,加入如下代碼以使地圖控制項佔滿整個視圖:
void CXXView::OnSize(UINT nType, int cx, int cy){CView::OnSize(nType, cx, cy);// TODO: 在此處添加訊息處理常式代碼if(m_Map.m_hWnd == NULL)return;if(IsWindow(m_Map.m_hWnd)){CRect rect;GetClientRect(&rect);m_Map.MoveWindow(rect,FALSE);m_Map.ZoomToPrev();}}
7、接下來就是要顯示了,可以在DOC類中利用預設的Serialize函數獲得檔案路徑,比如這樣:
#pragma warning(disable:4996) // 調用strlwr 函數的時候會出錯 不加這句的的話
void CSeXXDoc::Serialize(CArchive& ar){if (ar.IsStoring()){// TODO: 在此添加儲存代碼}else{// TODO: 在此添加載入代碼CFile *p_file = ar.GetFile();CString filePathTem = m_filePath;CString fileExtTem = m_fileExt;m_filePath = p_file->GetFilePath();char * nameTem = m_filePath.GetBuffer();char * ext = strlwr(strrchr(nameTem,'.') + 1);m_fileExt = ext;CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd();CXXView * pView = (CXXView *)pFrame->GetActiveView();if(m_fileExt == "tif"){pView->DrawImage(m_filePath);}else if(m_fileExt == "shp"){pView->DrawShp(m_filePath);}else{AfxMessageBox(_T("暫時只支援*.tif *.shp"));return;}}}
m_filePath可以聲明為DOC的一個共有成員變數即可
然後在view類去實現對應的顯示操作即可
8、顯示tif
void CXXView::DrawImage(CString filePath){// 建立映像介面開啟映像加入地圖m_Map.RemoveAllLayers(); mapWindow::IImagePtr pImage;pImage.CreateInstance(__uuidof(mapWindow::Image));pImage->Open(_bstr_t(filePath),mapWindow::USE_FILE_EXTENSION,TRUE,NULL);m_Map.AddLayer(pImage,true); Invalidate();}
9、顯示shp
void CXXView::DrawShp(CString filePath){// 建立shp介面開啟shp檔案加入地圖m_Map.RemoveAllLayers(); mapWindow::IShapefilePtr pShapefilebound;pShapefilebound.CreateInstance(__uuidof(mapWindow::Shapefile));pShapefilebound->Open(_bstr_t(filePath),false);m_Map.AddLayer(pShapefilebound,true);Invalidate();}
這樣就完成顯示操作了,怎麼實現漫遊等其他動作了。。
網上搜了很久,沒找到答案,最後在一篇老外的文章上找到瞭解決方法,也是看了很久才明白他說的意思。
網上看的關於漫遊,放大,縮小的c#代碼是這樣的
基本的地圖操作放大:axMap1.CursorMode = MapWinGIS.tkCursorMode.cmZoomIn;縮小:axMap1.CursorMode = MapWinGIS.tkCursorMode.cmZoomOut;漫遊:axMap1.CursorMode = MapWinGIS.tkCursorMode.cmPan;全幅:axMap1.ZoomToMaxExtents();
所以對於的c++代碼應該也是和這個類似的,
有說是這樣寫的,好像是百度空間的一個文章,不記得連結了,直接摘抄一些那個老外的文章上的代碼
map.SetCursorMode(MapWinGIS::tkCursorMode::cmPan);
但是我加的代碼中找了很久都沒有SetCursorMode這個方法,這要怎麼設定,這個文章老外在討論的方法,好像是直接給控制項添加一個變數什麼什麼的,也不知道在哪個地方添加,又搜尋了一番,原來還有一種使用mapwingis的方法,就是在一個對話方塊中添加這個mapwingis控制項,但是我的toolbox上面也沒有這個控制項。。最後發現原來這個是要手動添加進去的。具體的添加辦法也是在老外的那個論壇上看見的,連結暫時找不到了,有兩種添加方法
一個是直接在對話方塊上左鍵單擊然後選擇添加activex控制項,第二個是 工具菜單下的選擇工具箱菜單後選擇com組件中找到map control 1.0即可,然後可以看到這個控制項的屬性中確實有這個設定模式的,而且改了以後也是有效
然後為這個對話方塊的添加一個類,在為這個mapwingis控制項添加一個變數,關聯到之前的CDmap.h和CDmap.cpp中,發現一大推錯誤。。不過沒關係,這裡我發現了怎麼添加SetCursorMode這個介面的方法了。
void SetCursorMode(long propVal){SetProperty(0x3, VT_I4, propVal);}
其他的沒用的直接刪了就可以了,也就是說只要在CDmap.h中把這個介面添加進去就可以了。
後面這樣在需要的地方這樣調用就可以了
m_Map.SetCursorMode(mapWindow::tkCursorMode::cmZoomOut);
這個tkCursorMode有這麼多枚舉的,按需調用即可
enum{ cmZoomIn = 0, cmZoomOut = 1, cmPan = 2, cmSelection = 3, cmNone = 4, cmMeasure = 5, cmAddShape = 6, cmEditShape = 8, cmSplitByPolyline = 9, cmIdentify = 10, cmMoveShapes = 11, cmRotateShapes = 12, cmSelectByPolygon = 13, cmEraseByPolygon = 14, cmSplitByPolygon = 15, cmClipByPolygon = 16}tkCursorMode;
mapwingis c++ mfc 改變游標狀態達到放大縮小平移的效果