question about custom symbol in arcmap

2521
3
04-05-2013 07:22 AM
taishengchen
New Contributor
I write a custom symbol component like logomarker symbol ,but i use agg instead of gdi. When I open shape files in arcmap and use my custom symbol to render the data, It is successful. However , when I open geodatabase files,as the same as shape files, It will be fail. It render blank. When I load this data again. It will render with the default symbol correct. Why?

I use aggplus which is encapsulated like GDI+. the main code is follow(full code about main class in attachment):

Aggplus::Graphics *m_pGraphics;

STDMETHODIMP CCartoSymbolMarker::SetupDC(OLE_HANDLE hDC, ITransformation *Transformation)
{
m_ipTrans = Transformation;
m_pGraphics = Graphics::FromHDC((HDC)hDC);
return S_OK;
}

STDMETHODIMP CCartoSymbolMarker::Draw(IGeometry *Geometry)
{
if (!Geometry)
return E_POINTER;

IPointPtr spPoint(Geometry);
if (spPoint == NULL)
return E_FAIL;

double x=0, y=0;
FromMapPoint((IDisplayTransformation*)m_ipTrans, spPoint, &x, &y);

Pen myPen(Color(255,0,0,255), 1);
m_pGraphics->DrawRectangle(&myPen, x, y, 10, 20);
return S_OK;
}

STDMETHODIMP CCartoSymbolMarker::ResetDC()
{
delete m_pGraphics;
m_pGraphics = NULL;
return S_OK;
}


Aggplus Graphics class:

Graphics *Graphics::FromHDC(HDC hdc) { return(new Graphics(hdc)); }

Graphics::Graphics(HDC hdc) : m_dwConfigFlags(0)
{
RECT clipBox;
::GetClipBox(hdc, &clipBox);
int nW=clipBox.right-clipBox.left;
int nH=clipBox.bottom-clipBox.top;
ASSERT(nW>0 && nH>0);
z_Create(nW, nH, -4*nW, NULL);
m_dwConfigFlags|=def_flag_G_FromHDC;
m_fromhdc_HDC=hdc;
m_fromhdc_X=clipBox.left;
m_fromhdc_Y=clipBox.top;
}


Graphics::~Graphics()
{
#ifdef def_AP_Update_Dc_at_End
if(m_dwConfigFlags & def_flag_G_FromHDC)
{
BITMAPINFO hDib;
memset(&hDib, 0, sizeof(BITMAPINFO));
hDib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
hDib.bmiHeader.biWidth = m_dwWidth;
hDib.bmiHeader.biHeight = m_dwHeight;
hDib.bmiHeader.biPlanes = 1;
hDib.bmiHeader.biBitCount = 32;
hDib.bmiHeader.biCompression = BI_RGB;
hDib.bmiHeader.biSizeImage = m_dwWidth * m_dwHeight * 4;
#ifndef _X_NODCAlpha_
LPVOID pBits;
HBITMAP hBitmap = CreateDIBSection(m_fromhdc_HDC, &hDib, DIB_RGB_COLORS, &pBits, NULL, 0);

if(!hBitmap) ASSERT(FALSE);
else
{
memcpy(pBits, buffer, m_dwWidth * m_dwHeight * 4);
HDC mdc=CreateCompatibleDC( m_fromhdc_HDC );
if(!mdc) ASSERT(FALSE);
else
{
HBITMAP hbmOld=(HBITMAP)::SelectObject(mdc, hBitmap);
BLENDFUNCTION bln;
bln.BlendOp=AC_SRC_OVER;
bln.BlendFlags=0;
bln.SourceConstantAlpha=255;
bln.AlphaFormat=AC_SRC_ALPHA;
AlphaBlend(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, m_dwWidth, m_dwHeight, bln);
//BitBlt(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, SRCCOPY);
::SelectObject(mdc, hbmOld);
//::GdiFlush();
DeleteDC(mdc);
}
::DeleteObject(hBitmap);
}
#else
SetDIBitsToDevice(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight,
0, 0, 0, m_dwHeight,
buffer, &hDib, DIB_RGB_COLORS);
#endif //_X_NODCAlpha_
}
#endif //def_AP_Update_Dc_at_End


delete(m_agg_pREN);
delete(m_agg_ppixf);
if(!(m_dwConfigFlags&def_flag_G_ExtBuffer))
{
delete(buffer);
}
}

result:

custom symbol in arcmap symbol selector

[ATTACH=CONFIG]23246[/ATTACH]

shape file use my custom symbol, correct

[ATTACH=CONFIG]23243[/ATTACH]

geodatabase use my custom symbol. fail and blank

[ATTACH=CONFIG]23244[/ATTACH]

load the data again , it render correct with defalut symbol, but data is twice

[ATTACH=CONFIG]23245[/ATTACH]
0 Kudos
3 Replies
RobertBorchert
Frequent Contributor III
Unfortunately lots of things change between shapefiles and geodatabases.  Like brackets and quotation marks.

Kind of late but you best best with custom symbols is to stick with using Fonts then they will work with shapefiles, geodatabases, sde (yea things change again when going to sde) and ArcGIS online.


I write a custom symbol component like logomarker symbol ,but i use agg instead of gdi. When I open shape files in arcmap and use my custom symbol to render the data, It is successful. However , when I open geodatabase files,as the same as shape files, It will be fail. It render blank. When I load this data again. It will render with the default symbol correct. Why?

I use aggplus which is encapsulated like GDI+. the main code is follow(full code about main class  in attachment):

Aggplus::Graphics *m_pGraphics;

STDMETHODIMP CCartoSymbolMarker::SetupDC(OLE_HANDLE hDC, ITransformation *Transformation)
{
    m_ipTrans = Transformation;
    m_pGraphics = Graphics::FromHDC((HDC)hDC);
    return S_OK;
}

STDMETHODIMP CCartoSymbolMarker::Draw(IGeometry *Geometry)
{
    if (!Geometry)
        return E_POINTER;

    IPointPtr spPoint(Geometry);
    if (spPoint == NULL)
        return E_FAIL;

    double x=0, y=0;
    FromMapPoint((IDisplayTransformation*)m_ipTrans, spPoint, &x, &y);

    Pen myPen(Color(255,0,0,255), 1);
    m_pGraphics->DrawRectangle(&myPen, x, y, 10, 20);
    return S_OK;
}

STDMETHODIMP CCartoSymbolMarker::ResetDC()
{
    delete m_pGraphics;
    m_pGraphics = NULL;
    return S_OK;
}


Aggplus Graphics class:

Graphics *Graphics::FromHDC(HDC hdc) { return(new Graphics(hdc)); }

Graphics::Graphics(HDC hdc) : m_dwConfigFlags(0)
{
RECT clipBox;
::GetClipBox(hdc, &clipBox);
int nW=clipBox.right-clipBox.left;
int nH=clipBox.bottom-clipBox.top;
ASSERT(nW>0 && nH>0);
z_Create(nW, nH, -4*nW, NULL);
m_dwConfigFlags|=def_flag_G_FromHDC;
m_fromhdc_HDC=hdc;
m_fromhdc_X=clipBox.left;
m_fromhdc_Y=clipBox.top;
}


Graphics::~Graphics()
{
#ifdef def_AP_Update_Dc_at_End
if(m_dwConfigFlags & def_flag_G_FromHDC)
  {
   BITMAPINFO hDib;
   memset(&hDib, 0, sizeof(BITMAPINFO));
   hDib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   hDib.bmiHeader.biWidth = m_dwWidth;
   hDib.bmiHeader.biHeight = m_dwHeight;
   hDib.bmiHeader.biPlanes = 1;
   hDib.bmiHeader.biBitCount = 32;
   hDib.bmiHeader.biCompression = BI_RGB;
   hDib.bmiHeader.biSizeImage = m_dwWidth * m_dwHeight * 4;
#ifndef _X_NODCAlpha_
   LPVOID pBits;
   HBITMAP hBitmap = CreateDIBSection(m_fromhdc_HDC, &hDib, DIB_RGB_COLORS, &pBits, NULL, 0);

   if(!hBitmap) ASSERT(FALSE);
   else
    {
     memcpy(pBits, buffer, m_dwWidth * m_dwHeight * 4);
     HDC mdc=CreateCompatibleDC( m_fromhdc_HDC );
     if(!mdc) ASSERT(FALSE);
     else
      {
       HBITMAP hbmOld=(HBITMAP)::SelectObject(mdc, hBitmap);
       BLENDFUNCTION bln;
       bln.BlendOp=AC_SRC_OVER;
       bln.BlendFlags=0;
       bln.SourceConstantAlpha=255;
       bln.AlphaFormat=AC_SRC_ALPHA;
      AlphaBlend(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, m_dwWidth, m_dwHeight, bln);
       //BitBlt(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight, mdc, 0, 0, SRCCOPY);
       ::SelectObject(mdc, hbmOld);
       //::GdiFlush();
       DeleteDC(mdc);
      }
     ::DeleteObject(hBitmap);
    }
   #else
    SetDIBitsToDevice(m_fromhdc_HDC, m_fromhdc_X, m_fromhdc_Y, m_dwWidth, m_dwHeight,
                              0, 0, 0, m_dwHeight,
                              buffer, &hDib, DIB_RGB_COLORS);
   #endif //_X_NODCAlpha_
  }
#endif //def_AP_Update_Dc_at_End


delete(m_agg_pREN);
delete(m_agg_ppixf);
if(!(m_dwConfigFlags&def_flag_G_ExtBuffer))
{
     delete(buffer);
}
}

result:

custom symbol in arcmap symbol selector

[ATTACH=CONFIG]23246[/ATTACH]

shape file use my custom symbol, correct

[ATTACH=CONFIG]23243[/ATTACH]

geodatabase use my custom symbol. fail and blank

[ATTACH=CONFIG]23244[/ATTACH]

load the data again , it render correct with defalut symbol, but data is twice

[ATTACH=CONFIG]23245[/ATTACH]
0 Kudos
by Anonymous User
Not applicable
Original User: ts_chen

Unfortunately lots of things change between shapefiles and geodatabases.  Like brackets and quotation marks.

Kind of late but you best best with custom symbols is to stick with using Fonts then they will work with shapefiles, geodatabases, sde (yea things change again when going to sde) and ArcGIS online.



It can be render correct when I using gdi or gdi+
0 Kudos
taishengchen
New Contributor
It can be render correct when I using gdi or gdi+


My entire code use aggplus is in attachment
0 Kudos