C++ DrawPolygon problem?

Feb 27, 2012 at 10:28 AM
Edited Feb 27, 2012 at 10:29 AM

Dear Friend, I want ask how to use drawpolygon in C++,My code is here:

long lableh = m_Map.NewDrawing(1);
double pntx[] = {111,111,114,114,111};

double pnty[] = {21,23,23,21,21};

SAFEARRAY *psx;

psx = SafeArrayCreateVector(VT_R8, 0, 5);

double *pData;

HRESULT hr = SafeArrayAccessData(psx, (void **)&pData);

memcpy(pData, &pntx, sizeof(pntx[0])*5);

SafeArrayUnaccessData(psx);
SAFEARRAY *psy;

psy = SafeArrayCreateVector(VT_R8, 0, 5);

double *pyData;

hr = SafeArrayAccessData(psy, (void **)&pyData);

memcpy(pyData, &pnty, sizeof(pnty[0])*5);

SafeArrayUnaccessData(psy);
VARIANT *vax=new VARIANT;

VARIANT *vay=new VARIANT;

VariantInit( vax );

VariantInit( vay );
vax->vt = VT_ARRAY|VT_BYREF;

vax->pparray = &psx;
vay->vt = VT_ARRAY|VT_BYREF;

vay->pparray = &psy;

m_Map.DrawPolygon(vax,vay,5,0,true);


How to put VARIANT * xPoints, VARIANT * yPoints?

Oct 11, 2016 at 5:50 AM
Hi,

I am having the same issue. I am Using MapWinGIS 4.9.3. I am builing an application using C++ in MSVC 2015.
Here is code snippet:
void plotEllipse(int drawingLayer, double latInDeg, double longInDeg, double majorAxisInM, double minorAxisInM, double angleInDeg, OLE_COLOR plotColour)
{
   VARIANT* xplot = NULL;
   VARIANT* yplot = NULL;
   SAFEARRAY* xsafe = NULL;
   SAFEARRAY* ysafe = NULL;

   double angleInRad = angleInDeg / pi2;
   LONG polyCount = pi2 / 0.01;

   xplot = new VARIANT;
   yplot = new VARIANT;
   VariantInit(xplot);
   VariantInit(yplot);

   SAFEARRAYBOUND rgsabound;
   rgsabound.lLbound = 0;
   rgsabound.cElements = polyCount;

   xplot->vt = VT_ARRAY | VT_BYREF;
   yplot->vt = VT_ARRAY | VT_BYREF;

   xsafe = SafeArrayCreate(VT_R8, 1, &rgsabound);
   xplot->pparray = &xsafe;
   if (xplot->pparray == NULL)
   {
      return;
   }
   ysafe = SafeArrayCreate(VT_R8, 1, &rgsabound);
   yplot->pparray = &ysafe;
   if (yplot->pparray == NULL)
   {
      SafeArrayDestroy(xsafe);
      return;
   }
   double* xd = NULL;
   double* yd = NULL;
   SafeArrayAccessData(xsafe, (void**)&xd);
   SafeArrayAccessData(ysafe, (void**)&yd);
   LONG index = 0;

   double sinAngle = std::sin(angleInRad);
   double cosAngle = std::cos(angleInRad);

   for (double fineValue = 0; fineValue < pi2; fineValue += 0.01)
   {
      double sinStep = std::sin(fineValue);
      double cosStep = std::cos(fineValue);
      double x = (majorAxisInM*cosStep*cosAngle - minorAxisInM*sinStep*sinAngle);
      double y = (majorAxisInM*cosStep*sinAngle - minorAxisInM*sinStep*cosAngle);
      xd[index] = x;
      yd[index] = y;
      index++;
   }
   SafeArrayUnaccessData(xsafe);
   SafeArrayUnaccessData(ysafe);

   map->DrawPolygonEx(drawingLayer, xplot, yplot, polyCount, plotColour, 0);

   SafeArrayDestroy(xsafe);
   SafeArrayDestroy(ysafe);

   VariantClear(xplot);
   VariantClear(yplot);

   delete xplot;
   delete yplot;

   xplot = NULL;
   yplot = NULL;
}
When the application attempts to call the DrawPolygonEx function it crashes (Exception thrown.... Access violation).

My .tlh has this:
#pragma implementation_key(383)
inline HRESULT MapWinGIS::_DMap::DrawPolygonEx ( long LayerHandle, VARIANT * xPoints, VARIANT * yPoints, long numPoints, OLE_COLOR Color, VARIANT_BOOL fill ) {
    return _com_dispatch_method(this, 0x9b, DISPATCH_METHOD, VT_EMPTY, NULL, 
        L"\x0003\x400c\x400c\x0003\x0003\x000b", LayerHandle, xPoints, yPoints, numPoints, Color, fill);
}
Specifically the exception occurs when the _com_dispatch_method is called.

Any help would greatly be appreciated. I have spent hours searching for examples and have found no working results.
Nov 2, 2016 at 1:40 PM
Edited Nov 2, 2016 at 1:51 PM
Hello, I also meet this problem, i want to draw rectangle using DrawPolygon() function, and it pop up exception, my code is:
    m_map.ClearDrawings();
    m_map.NewDrawing(dlScreenReferencedList);

    //Draw line is OK
    //m_map.DrawLine(X, Y, x, Y, 2, 255);//TopLine
    //m_map.DrawLine(x, Y, x, y, 2, 255);
    //m_map.DrawLine(x, y, X, y, 2, 255);
    //m_map.DrawLine(X, y, X, Y, 2, 255);

    vector<double> X1;
    vector<double> Y1;
    X1.push_back(X);
    X1.push_back(x);
    X1.push_back(x);
    X1.push_back(X);
    Y1.push_back(Y);
    Y1.push_back(Y);
    Y1.push_back(y);
    Y1.push_back(y);
    VARIANT *X2 = new VARIANT; VARIANT *Y2 = new VARIANT;
    X2->vt = VT_ARRAY;
    X2->vt = VT_ARRAY;
// Vector2SafeArray is a fuction that implemented in MapWinGIS source code, i modify somewhere , see code in bottom
    if (Vector2SafeArray(&X1, VT_R8, X2) && Vector2SafeArray(&Y1, VT_R8, Y2))
    {
//I paste DrawPolygon() implement code from MapWinGIS source code here , and it can past the value of VARAINT type:
        SAFEARRAY *sax = *X2->pparray;
        SAFEARRAY *say = *Y2->pparray;
        double *xPts = (double *)sax->pvData;
        double *yPts = (double*)say->pvData;
    }
//pop up exception here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    m_map.DrawPolygon(X2, Y2, 4, 255, FALSE);
//pop up exception here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!





template <typename T>
bool Vector2SafeArray(std::vector<T> v, VARTYPE variantType, VARIANT arr)
{
SAFEARRAY FAR* psa = NULL;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;

if (v->size() > 0)
{
    rgsabound[0].cElements = v->size();
    psa = SafeArrayCreate(variantType, 1, rgsabound);

    if (psa)
    {
        T/*long HUGEP*/ *plng;
        SafeArrayAccessData(psa, (void HUGEP* FAR*)&plng);

        // can we copy bytes from set object directly?
        memcpy(plng, &(v->at(0)), sizeof(T)*v->size());
        SafeArrayUnaccessData(psa);

        arr->vt = VT_ARRAY | variantType | VT_SAFEARRAY;
        arr->pparray = &psa;
        return true;
    }

    arr->vt = VT_ARRAY | variantType| VT_SAFEARRAY;
    arr->pparray = &psa;
    return false;
}
else
{
    // no elements or a problem with creation
    rgsabound[0].cElements = 0;
    psa = SafeArrayCreate(variantType, 1, rgsabound);

    arr->vt = VT_ARRAY | variantType;
    arr->pparray = &psa;
    return false;
}
}


Many thanks !
Coordinator
Nov 3, 2016 at 8:01 AM
Are you using the latest version of MapWinGIS?
We recently moved to GitHub: https://github.com/MapWindow/MapWinGIS

Why did you change Vector2SafeArray? If you feel it is wrong, please let us know so we can adjust it in the main code.

I have no experience with using MapWinGIS using C++. It seems you have a lot of experience with C++. Did you try to debug MapWinGIS to catch the exception?
Nov 17, 2016 at 10:38 PM
Hello, the version of MapWinGIS in my computer is 4.0.3.5, 32bit, i am not sure whether it is newest version.
I change Vector2SafeArray function to fit for DrawPolygon first 2 [in] args, because DrawPolygon only receive the pparray VARIANT type according to the mapwingis C++ source code.
Yes, i am teaching GIS programing with c++, i also use C#.net or VB.net on some GIS applications.
I try to catch the excption, but i have not ever compiled the source code, I did not know how to debug it from MapWinGIS ActiveX binary file.
Regards

[email removed]
Nov 22, 2016 at 1:26 PM
In the end, I found a workaround which was to draw the polygon in a shapefile. If I come across the correct solution and find out why the crash is occurring I will post here.
Apr 21 at 9:07 AM
Hello!
If the decision of this task interests someone else?
I solved this problem.
It is necessary to transfer to the DrawPolygonEx method VARIANT* to pvarVal;//VT_BYREF|VT_VARIANT.
"A pointer to another VARIANTARG is passed in pvarVal. This referenced VARIANTARG, pvarVal, cannot be another VT_VARIANT|VT_BYREF. This value can be used to support languages that allow functions to change the types of variables passed by reference."

Example:
USES_CONVERSION;
    
            long num_points = sAttribute->points.size();

            SAFEARRAY * vDataX = SafeArrayCreateVector(VT_R8,  0,  num_points); 
            SAFEARRAY * vDataY = SafeArrayCreateVector(VT_R8,  0,   num_points); 
            if(vDataX == NULL || vDataY == NULL) 
                return;

        
            SafeArrayLock(vDataX);
            SafeArrayLock(vDataY);

            for(long i = 0 ;i<num_points;i++)
            {
                double x_proj ;
                double y_proj ;
                m_AxMap.m_MapPtr->DegreesToProj(sAttribute->points[i].Y, sAttribute->points[i].X,&x_proj,&y_proj);


                SafeArrayPutElement(vDataX, &i, (void*)&x_proj);
                SafeArrayPutElement(vDataY, &i, (void*)&y_proj);
        
            }
            
            SafeArrayUnlock(vDataX);
            SafeArrayUnlock(vDataY);
            
            VARIANT vX;
            VARIANT vY;
            vX.vt =  VT_BYREF|VT_ARRAY;
            vY.vt =  VT_BYREF|VT_ARRAY;
            vX.pparray = &(vDataX);
            vY.pparray = &(vDataY);
            
          
            m_AxMap.m_MapPtr->DrawPolygonEx(drawHandle,vX.pvarVal ,vY.pvarVal, num_points,  233,true);


            SafeArrayDestroy(vDataX);
            SafeArrayDestroy(vDataY);

            VariantClear(&vX);
            VariantClear(&vY);
Yours faithfully, Vitaly.