📄 mapxsampview.cpp
字号:
// more than 1 user draw layer
void CMapxSampleView::OnDrawUserLayer(LPDISPATCH Layer, long hOutputDC, long hAttributeDC, LPDISPATCH RectFull, LPDISPATCH RectInvalid)
{
float barWidth =(float)0.5, barHeight =(float)0.08;
float startX =(float).3, startY =(float).3;
long x1, y1;
int i;
// attach to dc that mapx passed us so we can use
// mfc CDC object. (we will detach before exiting this method
CDC dc;
CPen pen;
CBrush brushRed, brushWhite, *pOldBrush;
CFont *pOldFont;
pen.CreatePen(0,1,(COLORREF)0);
brushRed.CreateSolidBrush(255);
brushWhite.CreateSolidBrush(16777215);
dc.Attach((HDC)hOutputDC);
dc.SetAttribDC((HDC)hAttributeDC);
//Set map mode to HI-English
dc.SetMapMode(MM_HIENGLISH);
//Set pen to black
CPen *pOldPen = dc.SelectObject(&pen);
pOldBrush = dc.SelectObject(&brushRed);
//convert to HiEnglish, Conversion needed because one HIENGLISH unit is .001 inch
x1=(long)(startX*1000);
y1=(long)(startY*1000);
barWidth*=1000;
barHeight*=1000;
for (i=0; i<=1; i++) {
long x2 =(long)(barWidth+x1);
long y2 =(long)(barHeight+y1);
/*** First Section ***/
if (i==0) {
dc.SelectObject(&brushRed); //Red
}
else {
dc.SelectObject(&brushWhite); //White
}
// with mapMode HIENGLISH, positive is x to the right, positive y is up
dc.Rectangle(x1, -y1, x2, -y2);
/*** Second Section ***/
x1=x2;
x2=(long)(barWidth+x1);
if (i==0) {
dc.SelectObject(&brushWhite); //White
}
else {
dc.SelectObject(&brushRed); //Red
}
dc.Rectangle(x1, -y1, x2, -y2);
/*** Third Section ***/
x1=x2;
x2=(long)(barWidth*2+x1);
if (i==0) {
dc.SelectObject(&brushRed); //Red
}
else {
dc.SelectObject(&brushWhite); //White
}
dc.Rectangle(x1, -y1, x2, -y2);
/*** Reset Values for bottom bar pass***/
x1=(long)(startX*1000);
y1=y2;
} // End For
// Calculate Pixels Per Inch
CPoint pt(1000, 1000); // In HIENGLISH 1000 units = 1 inch
dc.LPtoDP(&pt); // Convert inch to pixel
long lPixPerInch = pt.x;
CRect rc;
CView::GetClientRect(&rc);
float screenX, screenY;
double mapX1, mapY1;
// subtract lPixPerInch from center to get 1 inch to left of Center
screenX = (float)(rc.right/2-lPixPerInch);
screenY = (float)(rc.bottom/2);
try {
m_ctrlMapX.ConvertCoord(&screenX, &screenY, &mapX1, &mapY1, miScreenToMap);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
double mapX2, mapY2;
// add lPixPerInch to center to get 1 inch to right of Center
screenX = (float)(rc.right/2+lPixPerInch);
screenY = (float)(rc.bottom/2);
try {
m_ctrlMapX.ConvertCoord(&screenX, &screenY, &mapX2, &mapY2, miScreenToMap);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
CFont font;
font.CreatePointFont(100, "Arial", &dc);
pOldFont = dc.SelectObject(&font);
dc.SetTextColor(0); //Black
dc.SetBkMode(TRANSPARENT);
// Output ScaleBar start Label = 0
x1=(long)(startX*1000);
y1=(long)((startY-.2)*1000);
dc.TextOut(x1,-y1,"0");
// Output label for distance of 1 inch
x1=(long)(barWidth*2+startX*1000);
CString str;
str.Format("%.0f",m_ctrlMapX.Distance(mapX1, mapY1, mapX2, mapY2)/2);
// Need to center text over center line. will move it 60 units for each character
int iCenterAdjustment = 60*str.GetLength();
dc.TextOut(x1-iCenterAdjustment,-y1,str);
// Output label for distance of 2 inches
x1=(long)(barWidth*4+startX*1000);
str.Format("%.0f",m_ctrlMapX.Distance(mapX1, mapY1, mapX2, mapY2));
// Need to center text over end line. will move it 60 units for each character
iCenterAdjustment = 60*str.GetLength();
dc.TextOut(x1-iCenterAdjustment,-y1,str);
// Output label for Units "Miles"
x1=(long)(barWidth*2+startX*1000);
y1=(long)((startY+.2)*1000);
// Need to center text over center line. will move it 60 units for each character
str.Format("Miles");
iCenterAdjustment = 60*str.GetLength();
dc.TextOut(x1-iCenterAdjustment,-y1,str);
dc.SelectObject(pOldBrush);
dc.SelectObject(pOldPen);
dc.SelectObject(pOldFont);
// detach dc so destructore won't call Release it
dc.ReleaseAttribDC();
dc.Detach();
}
// The CUSARecordset class' GetDefaultDBName()
// method brings up a file picker for finding
// the mapstats.mdb file.
void CMapxSampleView::OnMapAdddaodata()
{
try {
if (!m_daoUSCust.IsOpen()) {
m_daoUSCust.Open();
}
}
catch (CDaoException *e) {
e->ReportError();
e->Delete();
return;
}
short Type;
VARIANT SourceData;
VARIANT Name;
VARIANT GeoField;
VARIANT BindLayerName;
VARIANT Fields;
CString strName= "DAO US Customers";
// set up optional parameters
// could also use COptionalVariant class from mapx.h
// will not be used
COptionalVariant SecondaryGeoField;
// let mapx auto detect geofield
// this is the same as using COptionalVariant
GeoField.vt = VT_BSTR;
GeoField.bstrVal = CString("STATE").AllocSysString();
// let mapx find which layer to bind to
BindLayerName.vt = VT_BSTR;
BindLayerName.bstrVal = CString("USA").AllocSysString();
// use all fields with defaults
Fields.vt = VT_ERROR;
Fields.scode = DISP_E_PARAMNOTFOUND;
// set the name of our dataset
Name.vt = VT_BSTR;
Name.bstrVal = strName.AllocSysString();
// set up source data
// Note: it is best to keep the dao recordset around until mapx is done with it
Type = miDataSetDAO;
SourceData.vt = VT_DISPATCH;
SourceData.pdispVal = m_daoUSCust.m_pDAORecordset;
try {
// now add the dataset to the datasets collection
CMapXDataset ds = m_ctrlMapX.GetDatasets().Add(Type, SourceData, Name, GeoField, SecondaryGeoField, BindLayerName, Fields, COptionalVariant());
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
}
void CMapxSampleView::OnPolyToolUsedMap(short ToolNum, long Flags, LPDISPATCH Points, BOOL bShift, BOOL bCtrl, BOOL FAR* EnableDefault)
{
// see CSampleDlg for example on usage on creating polygons or lines
// calc distance so far
if (ToolNum == MYTOOL_DISTANCE) {
CMapXPoints pts;
long n;
long i;
try {
pts.AttachDispatch(Points, FALSE); // don't auto release
double dDistanceTot = 0.0;
n = pts.GetCount();
for (i=1; i<n; i++) {
CMapXPoint pt1 = pts.Item(i);
CMapXPoint pt2 = pts.Item(i+1);
double d = m_ctrlMapX.Distance(pt1.GetX(), pt1.GetY(), pt2.GetX(), pt2.GetY());
dDistanceTot += d;
}
CString str;
str.Format("Distance Tot: %f", dDistanceTot);
((CMainFrame *)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(0, str);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
}
void CMapxSampleView::OnClickMap()
{
}
void CMapxSampleView::OnDblClickMap()
{
}
void CMapxSampleView::OnErrorMap(short Number, BSTR FAR* Description, long Scode, LPCTSTR Source, LPCTSTR HelpFile, long HelpContext, BOOL FAR* CancelDisplay)
{
}
void CMapxSampleView::OnKeyDownMap(short FAR* KeyCode, short Shift)
{
}
void CMapxSampleView::OnKeyPressMap(short FAR* KeyAscii)
{
}
void CMapxSampleView::OnKeyUpMap(short FAR* KeyCode, short Shift)
{
}
void CMapxSampleView::OnMouseDownMap(short Button, short Shift, float X, float Y)
{
}
void CMapxSampleView::OnSelectionChangedMap()
{
}
void CMapxSampleView::OnResolveDataBindMap(short Flag, short NumMatches, const VARIANT FAR& Matches, short FAR* Choice, BOOL FAR* Cancel)
{
CResolveDatabind dlg(this);
CStringList strList;
dlg.m_nChoice = 0;
switch(Flag) {
case miChooseField:
dlg.m_strTitle = _T("Choose Field");
break;
case miChooseLayer:
dlg.m_strTitle = _T("Choose Layer");
break;
case miChooseGeoSet:
// just use default choice
return;
// could let user pick
//dlg.m_strTitle = _T("Choose Geoset");
break;
}
if (Matches.vt & VT_ARRAY) {
long lLowerBound, lUpperBound;
HRESULT hr = SafeArrayGetLBound(Matches.parray,1,&lLowerBound);
if(FAILED(hr)) {
return;
}
hr = SafeArrayGetUBound(Matches.parray,1,&lUpperBound);
if(FAILED(hr)) {
return;
}
for( long l=lLowerBound; l<=lUpperBound; l++) {
BSTR bstr;
HRESULT hr = SafeArrayGetElement(Matches.parray, &l, &bstr);
if (FAILED(hr)) {
return;
}
CString str = bstr;
::SysFreeString(bstr);
strList.AddTail(str);
} // for
} // if array
dlg.m_pStrList = &strList;
if (dlg.DoModal()==IDOK && dlg.m_nChoice != -1) {
// Mapx expects a 1 based index
*Choice = (int)dlg.m_nChoice+1;
}
}
// this example just uses hard coded values for 2 states
// you can get the data from wherever you like
static TCHAR *szUnboundData[2][2] = { _T("NY"), _T("15000000"), _T("MA"), _T("11500000") };
void CMapxSampleView::OnRequestDataMap(LPCTSTR DataSetName, long Row, short Field, VARIANT FAR* Value, BOOL FAR* Done)
{
TRACE("Unbound data request for layer: '%s', row, col: %d %d\n", DataSetName, Row, Field);
if (Row >= 1 && Row <= 2) {
CString strVal = szUnboundData[Row-1][Field-1];
Value->vt = VT_BSTR;
Value->bstrVal = strVal.AllocSysString();
*Done = FALSE;
}
else {
*Done = TRUE;
}
}
void CMapxSampleView::OnDataMismatchMap(LPCTSTR DataSetName, long Row, BSTR FAR* GeoFieldValue)
{
}
void CMapxSampleView::OnAnnotationAddedMap(LPDISPATCH Annotation)
{
}
void CMapxSampleView::OnAnnotationChangedMap(short ChangeType, LPDISPATCH Annotation, BOOL FAR* EnableDefault)
{
}
void CMapxSampleView::OnMapToolDistancetool()
{
m_ctrlMapX.SetCurrentTool(MYTOOL_DISTANCE);
}
void CMapxSampleView::OnMapToolInfotool()
{
try {
if (m_ctrlMapX.GetDatasets().GetCount() == 0) {
AfxMessageBox("This info tool requires that a dataset be added.");
return;
}
m_ctrlMapX.SetCurrentTool(MYTOOL_INFO);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
void CMapxSampleView::OnOdbcNormalAuto()
{
try {
COleVariant SourceData;
CMapXODBCQueryInfo ODBCParam;
CMapXDatasets ds = m_ctrlMapX.GetDatasets();
// this assumes you have an Access DataSource called MapStatsV4 pointing
// to the MapStats.mdb that ships with MapX. If the DataSource param is left
// out, the user will be prompted for an ODBC datasource.
// Allocate ODBCQueryInfo object
ODBCParam.CreateDispatch("MapX.ODBCQueryInfo.4");
ODBCParam.SetConnectString("ODBC;");
ODBCParam.SetSqlQuery("select * From US_CUST");
ODBCParam.SetDataSource("MapStatsV4");
SourceData.vt = VT_DISPATCH;
SourceData.pdispVal = ODBCParam.m_lpDispatch;
SourceData.pdispVal->AddRef ();
if (!m_bODBCDynamic) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -