MyDynamicLayer.cpp
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // #include <stdio.h> #include <math.h> #include "MyDynamicLayer.h" #ifdef ESRI_UNIX #include <unistd.h> #else #include <direct.h> #include <time.h> #endif #define NEGATIVE_VAL(q) q<0?q:-q #define ABSOLUTE_VAL(q) q<0?-q:q static char *get_current_directory() { static char sBuf[1024]; #ifdef ESRI_WINDOWS _getcwd(sBuf, 1024); #else getcwd(sBuf, 1024); #endif return sBuf; } MyDynamicLayer::MyDynamicLayer(IMap* pMap): m_ipMap(pMap), m_bAnimate(false), m_bDynamicGlyphsCreated(false) { put_Name(L"Tracks"); m_bIsDirty[esriDDPImmediate] = VARIANT_TRUE; m_bIsDirty[esriDDPCompiled ] = VARIANT_TRUE; m_bAnimate = true; srand(time(NULL)); } MyDynamicLayer::~MyDynamicLayer() { // } void MyDynamicLayer::UpdateItems(IDisplay* pDisplay) { IScreenDisplayPtr ipScreenDisplay = pDisplay; if (ipScreenDisplay == 0) return; IDisplayTransformationPtr ipDisplayTransformation; ipScreenDisplay->get_DisplayTransformation(&ipDisplayTransformation); IEnvelopePtr ipFittedBounds; ipDisplayTransformation->get_FittedBounds(&ipFittedBounds); double dXmax, dYmax, dXmin, dYmin; ipFittedBounds->get_XMax(&dXmax); ipFittedBounds->get_YMax(&dYmax); ipFittedBounds->get_XMin(&dXmin); ipFittedBounds->get_YMin(&dYmin); SNavigationData* pNavData = 0; int i; for (i=0 ; i<NUM_OF_ITEMS ; i++) { pNavData = &m_navData[i]; pNavData->x += pNavData->stepX; pNavData->y += pNavData->stepY; if (pNavData->x > dXmax) pNavData->stepX = NEGATIVE_VAL(pNavData->stepX); if (pNavData->x < dXmin) pNavData->stepX = ABSOLUTE_VAL(pNavData->stepX); if (pNavData->y > dYmax) pNavData->stepY = NEGATIVE_VAL(pNavData->stepY); if (pNavData->y < dYmin) pNavData->stepY = ABSOLUTE_VAL(pNavData->stepY); pNavData->azimuth = ((int)(360.0 + 90.0 - (atan2(pNavData->stepY, pNavData->stepX) * 180.0 / ESRI_PI))) % 360; } } void MyDynamicLayer::put_Animate(bool bAnimate) { m_bAnimate = bAnimate; } HRESULT MyDynamicLayer::CreateDynamicSymbols(IDynamicDisplay* pDynamicDisplay) { HRESULT hr = S_OK; IRgbColorPtr ipTransClr(CLSID_RgbColor); ipTransClr->put_Red (0); ipTransClr->put_Green(0); ipTransClr->put_Blue (0); IRgbColorPtr ipClr(CLSID_RgbColor); ipClr->put_Red (255); ipClr->put_Green(255); ipClr->put_Blue (255); ICharacterMarkerSymbolPtr ipCharMarkSym(CLSID_CharacterMarkerSymbol); IFontDisp *pFontDisp; IFont *pFont; ipCharMarkSym->get_Font(&pFontDisp); pFontDisp->QueryInterface(IID_IFont, (void **)&pFont); tagCY fontSize; fontSize.int64 = 32; pFont->put_Name(L"ESRI Environmental & Icons"); pFont->put_Size(fontSize); ipCharMarkSym->put_Color(ipClr); ipCharMarkSym->put_Font(pFontDisp); ipCharMarkSym->put_Size(40.0); ipCharMarkSym->put_Angle(0.0); ipCharMarkSym->put_CharacterIndex(36); IDynamicGlyphFactoryPtr ipDynamicGlyphFactory; hr = pDynamicDisplay->get_DynamicGlyphFactory(&ipDynamicGlyphFactory); hr = ipDynamicGlyphFactory->CreateDynamicGlyph(((ISymbolPtr)ipCharMarkSym), &m_ipMarkerGlphys[0]); ipCharMarkSym->put_Size(32); ipCharMarkSym->put_CharacterIndex(224); hr = ipDynamicGlyphFactory->CreateDynamicGlyph(((ISymbolPtr)ipCharMarkSym), &m_ipMarkerGlphys[1]); ipTransClr->put_Green(255); ipTransClr->put_Blue(255); char sBmpPath[1024]; #ifdef ESRI_WINDOWS sprintf(sBmpPath, "%s%c%s%c%s", get_current_directory(), '\\', "icons", '\\', "B2.bmp"); #else sprintf(sBmpPath, "%s%c%s%c%s", get_current_directory(), '/', "icons", '/', "B2.bmp"); #endif hr = ipDynamicGlyphFactory->CreateDynamicGlyphFromFile(esriDGlyphMarker, CComBSTR(sBmpPath), ipTransClr, &m_ipMarkerGlphys[2]); //hr = ipDynamicGlyphFactory->get_DynamicGlyph(1, esriDGlyphText, 1, &m_ipTextGlyph); long lGroupId = 0; hr = ipDynamicGlyphFactory->LoadDynamicGlyphsGroup(L"WhiteText.xml", &lGroupId); hr = ipDynamicGlyphFactory->get_DynamicGlyph(lGroupId, esriDGlyphText, 1, &m_ipTextGlyph); pFont->Release(); return S_OK; } // IDynamicLayer HRESULT MyDynamicLayer::get_DynamicLayerDirty(esriDynamicDrawPhase DynamicDrawPhase, VARIANT_BOOL* pDirty) { if (!pDirty) return E_POINTER; *pDirty = m_bIsDirty[DynamicDrawPhase]; return S_OK; } HRESULT MyDynamicLayer::put_DynamicLayerDirty(esriDynamicDrawPhase DynamicDrawPhase, VARIANT_BOOL bDirty) { m_bIsDirty[DynamicDrawPhase] = bDirty; return S_OK; } HRESULT MyDynamicLayer::get_DynamicRecompileRate(long* pDynamicRecompileRateTimeMS) { if (!pDynamicRecompileRateTimeMS) return E_POINTER; *pDynamicRecompileRateTimeMS = ANIMATION_CYCLE_TIME_MS; return S_OK; } HRESULT MyDynamicLayer::DrawDynamicLayer(esriDynamicDrawPhase phase, IDisplay* pDisplay, IDynamicDisplay* pDynamicDisplay) { if (!pDisplay || !pDynamicDisplay) return E_POINTER; VARIANT_BOOL bVisible; get_Visible(&bVisible); if (bVisible != VARIANT_TRUE) return S_OK; if (phase == esriDDPImmediate) { if (m_bIsDirty[esriDDPImmediate] == VARIANT_TRUE && !m_bDynamicGlyphsCreated) { GenerateNavigationData(pDisplay); CreateDynamicSymbols(pDynamicDisplay); m_bDynamicGlyphsCreated = true; m_bIsDirty[esriDDPImmediate] = VARIANT_FALSE; } } else if (m_bIsDirty[esriDDPCompiled] == VARIANT_TRUE) // Compiled Phase { if (m_bAnimate) UpdateItems(pDisplay); DrawItems(pDisplay, pDynamicDisplay); m_bIsDirty[esriDDPCompiled] = VARIANT_TRUE; } return S_OK; } HRESULT MyDynamicLayer::GenerateNavigationData(IDisplay* pDisplay) { IScreenDisplayPtr ipScreenDisplay = pDisplay; if (ipScreenDisplay == 0) return E_FAIL; IDisplayTransformationPtr ipDisplayTransformation; ipScreenDisplay->get_DisplayTransformation(&ipDisplayTransformation); IEnvelopePtr ipExtent; ipDisplayTransformation->get_FittedBounds(&ipExtent); double XStep, YStep, XMax, YMax, XMin, YMin; ipExtent->get_Width (&XStep); ipExtent->get_Height(&YStep); ipExtent->get_XMax (&XMax ); ipExtent->get_YMax (&YMax ); ipExtent->get_XMin (&XMin ); ipExtent->get_YMin (&YMin ); XStep /= 1000.0; YStep /= 1000.0; int i; SNavigationData* pNavData = 0; for (i=0 ; i<NUM_OF_ITEMS ; i++) { pNavData = &m_navData[i]; pNavData->stepX = XStep * GetRandomDouble(); pNavData->stepY = YStep * GetRandomDouble(); pNavData->x = XMin + (GetRandomDouble() * (XMax - XMin)); pNavData->y = YMin + (GetRandomDouble() * (YMax - YMin)); pNavData->azimuth = ((int)(360.0 + 90.0 - (atan2(pNavData->stepY, pNavData->stepX) * 180.0 / ESRI_PI))) % 360; pNavData->type = i % 3; } return S_OK; } void MyDynamicLayer::DrawItems(IDisplay* pDisplay, IDynamicDisplay* pDynamicDisplay) { IDynamicSymbolProperties2Ptr ipDynamicSymbolProperties = pDynamicDisplay; IDynamicCompoundMarker2Ptr ipDynamicCompoundMarker = pDynamicDisplay; double X, Y, heading; IPointPtr ipPoint(CLSID_Point); SNavigationData* pNavData = 0; int i; for (i=0 ; i<NUM_OF_ITEMS ; i++) { pNavData = &m_navData[i]; ipPoint->PutCoords(pNavData->x, pNavData->y); switch (pNavData->type) { case 0: sprintf(m_sIndex, "Item %.3d", i); sprintf(m_sHeading, "%.3f", pNavData->azimuth); sprintf(m_sX, "%.3f", pNavData->x); sprintf(m_sY, "%.3f", pNavData->y); ipDynamicSymbolProperties->put_Heading(esriDSymbolText,0.0); ipDynamicSymbolProperties->put_Heading(esriDSymbolMarker, pNavData->azimuth); ipDynamicSymbolProperties->put_RotationAlignment(esriDSymbolMarker, esriDSRAScreen); ipDynamicSymbolProperties->put_RotationAlignment(esriDSymbolText, esriDSRAScreen); ipDynamicSymbolProperties->SetScale(esriDSymbolMarker, 0.8, 0.8); ipDynamicSymbolProperties->SetColor(esriDSymbolMarker, 0.0, 0.0, 1.0, 1.0); ipDynamicSymbolProperties->SetColor(esriDSymbolText, 1.0, 1.0, 0.0, 1.0); ipDynamicSymbolProperties->putref_DynamicGlyph(esriDSymbolMarker, m_ipMarkerGlphys[0]); ipDynamicSymbolProperties->putref_DynamicGlyph(esriDSymbolText, m_ipTextGlyph); ipDynamicCompoundMarker->DrawCompoundMarker6 (ipPoint, m_bstrEmptyString, m_bstrEmptyString, CComBSTR(m_sIndex), CComBSTR(m_sHeading), CComBSTR(m_sY), CComBSTR(m_sX)); break; case 1: ipDynamicSymbolProperties->put_Heading(esriDSymbolMarker, pNavData->azimuth); ipDynamicSymbolProperties->put_RotationAlignment(esriDSymbolMarker, esriDSRANorth); ipDynamicSymbolProperties->SetScale(esriDSymbolMarker, 1.0, 1.0); ipDynamicSymbolProperties->SetColor(esriDSymbolMarker, 0.0, 1.0, 0.6, 1.0); ipDynamicSymbolProperties->putref_DynamicGlyph(esriDSymbolMarker, m_ipMarkerGlphys[1]); pDynamicDisplay->DrawMarker(ipPoint); break; case 2: ipDynamicSymbolProperties->put_Heading(esriDSymbolMarker, pNavData->azimuth + 180.0); ipDynamicSymbolProperties->put_RotationAlignment(esriDSymbolMarker, esriDSRANorth); ipDynamicSymbolProperties->SetScale(esriDSymbolMarker, 1.5, 1.5); ipDynamicSymbolProperties->SetColor(esriDSymbolMarker, 1.0, 1.0, 1.0, 1.0); ipDynamicSymbolProperties->putref_DynamicGlyph(esriDSymbolMarker, m_ipMarkerGlphys[2]); pDynamicDisplay->DrawMarker(ipPoint); break; } // end switch }// end for } inline double MyDynamicLayer::GetRandomDouble() { double value = ((double)rand() / (double)RAND_MAX); return value; }