<commit_before>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* iot_support at tid dot es
*
* Author: Ken Zangelin
*/
#include <stdio.h>
#include <string>

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "common/globals.h"
#include "orionTypes/areas.h"
#include "ngsi10/UpdateContextSubscriptionRequest.h"
#include "xmlParse/XmlNode.h"
#include "xmlParse/xmlParse.h"
#include "xmlParse/xmlUpdateContextSubscriptionRequest.h"

/* ****************************************************************************
*
* restriction -
*/
static int restriction(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a restriction"));
  ++reqData->ucsr.res.restrictions;

  return 0;
}

/* ****************************************************************************
*
* attributeExpression -
*/
static int attributeExpression(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got an attributeExpression: '%s'", node->value()));
  reqData->ucsr.res.restriction.attributeExpression.set(node->value());

  return 0;
}

/* ****************************************************************************
*
* operationScope -
*/
static int operationScope(xml_node<>* node, ParseData* reqData)
{
  Scope* newScopeP = new Scope();

  LM_T(LmtParse, ("Got an operationScope"));
  reqData->ucsr.scopeP = newScopeP;
  reqData->ucsr.res.restriction.scopeVector.push_back(reqData->ucsr.scopeP);

  return 0;
}

/* ****************************************************************************
*
* scopeType -
*/
static int scopeType(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a scopeType: '%s'", node->value()));
  reqData->ucsr.scopeP->type = node->value();
  return 0;
}

/* ****************************************************************************
*
* scopeValue -
*/
static int scopeValue(xml_node<>* node, ParseData* reqData)
{
  if (reqData->ucsr.scopeP->type == FIWARE_LOCATION || reqData->ucsr.scopeP->type == FIWARE_LOCATION)
  {
    //
    // If the scope type is FIWARE_LOCATION (or its deprecated variant), then the value of this scope is stored in 'circle' or 'polygon'.
    // The field 'value' is not used as more complexity is needed.
    // scopeP->value is here set to FIWARE_LOCATION, in an attempt to warn a future use of 'scopeP->value' when
    // instead 'circle' or 'polygon' should be used.
    //
    reqData->ucsr.scopeP->value = FIWARE_LOCATION;
    LM_T(LmtParse, ("Preparing scopeValue for '%s'", reqData->ucsr.scopeP->type.c_str()));
  }
  else
  {
    reqData->ucsr.scopeP->value = node->value();
    LM_T(LmtParse, ("Got a scopeValue: '%s' for scopeType '%s'", node->value(), reqData->ucsr.scopeP->type.c_str()));
  }

  return 0;
}

/* ****************************************************************************
*
* circle -
*/
static int circle(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circle"));
  reqData->ucsr.scopeP->areaType = orion::CircleType;
  return 0;
}

/* ****************************************************************************
*
* circleCenterLatitude -
*/
static int circleCenterLatitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circleCenterLatitude: %s", node->value()));
  reqData->ucsr.scopeP->circle.center.latitudeSet(node->value());

  return 0;
}

/* ****************************************************************************
*
* circleCenterLongitude -
*/
static int circleCenterLongitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circleCenterLongitude: %s", node->value()));
  reqData->ucsr.scopeP->circle.center.longitudeSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* circleRadius -
*/
static int circleRadius(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circleRadius: %s", node->value()));
  reqData->ucsr.scopeP->circle.radiusSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* circleInverted -
*/
static int circleInverted(xml_node<>* node, ParseData* parseDataP)
{
  LM_T(LmtParse, ("Got a circleInverted: %s", node->value()));

  parseDataP->ucsr.scopeP->circle.invertedSet(node->value());

  if (!isTrue(node->value()) && !isFalse(node->value()))
  {
    parseDataP->errorString = std::string("bad string for circle/inverted: /") + node->value() + "/";
    return 1;
  }

  return 0;
}

/* ****************************************************************************
*
* polygon -
*/
static int polygon(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygon"));
  reqData->ucsr.scopeP->areaType = orion::PolygonType;
  return 0;
}

/* ****************************************************************************
*
* polygonInverted -
*/
static int polygonInverted(xml_node<>* node, ParseData* parseDataP)
{
  LM_T(LmtParse, ("Got a polygonInverted: %s", node->value()));

  parseDataP->ucsr.scopeP->polygon.invertedSet(node->value());
  if (!isTrue(node->value()) && !isFalse(node->value()))
  {
    parseDataP->errorString = std::string("bad string for polygon/inverted: /") + node->value() + "/";
    return 1;
  }

  return 0;
}

/* ****************************************************************************
*
* polygonVertexList -
*/
static int polygonVertexList(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertexList"));
  return 0;
}

/* ****************************************************************************
*
* polygonVertex -
*/
static int polygonVertex(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertex - creating new vertex for the vertex list"));
  reqData->ucsr.vertexP = new orion::Point();
  reqData->ucsr.scopeP->polygon.vertexAdd(reqData->ucsr.vertexP);
  // reqData->ucsr.scopeP->polygon.vertexList.push_back(reqData->ucsr.vertexP);
  return 0;
}

/* ****************************************************************************
*
* polygonVertexLatitude -
*/
static int polygonVertexLatitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertexLatitude: %s", node->value()));
  reqData->ucsr.vertexP->latitudeSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* polygonVertexLongitude -
*/
static int polygonVertexLongitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertexLongitude: %s", node->value()));
  reqData->ucsr.vertexP->longitudeSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* duration -
*/
static int duration(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a duration: '%s'", node->value()));
  reqData->ucsr.res.duration.set(node->value());
  return 0;
}

/* ****************************************************************************
*
* notifyCondition -
*/
static int notifyCondition(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a Notify Condition"));
  reqData->ucsr.notifyConditionP = new NotifyCondition();
  reqData->ucsr.res.notifyConditionVector.push_back(reqData->ucsr.notifyConditionP);
  return 0;
}

/* ****************************************************************************
*
* notifyConditionType -
*/
static int notifyConditionType(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a Notify Condition Type: '%s'", node->value()));
  reqData->ucsr.notifyConditionP->type = node->value();
  return 0;
}

/* ****************************************************************************
*
* condValue -
*/
static int condValue(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a Cond Value: '%s'", node->value()));
  reqData->ucsr.notifyConditionP->condValueList.push_back(node->value());
  return 0;
}

/* ****************************************************************************
*
* subscriptionId -
*/
static int subscriptionId(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a subscriptionId: '%s'", node->value()));
  reqData->ucsr.res.subscriptionId.set(node->value());
  return 0;
}

/* ****************************************************************************
*
* throttling -
*/
static int throttling(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a throttling: '%s'", node->value()));
  reqData->ucsr.res.throttling.set(node->value());
  return 0;
}

/* ****************************************************************************
*
* ucsrInit -
*/
void ucsrInit(ParseData* reqData)
{
  reqData->ucsr.notifyConditionP       = NULL;
  reqData->ucsr.scopeP                 = NULL;
  reqData->ucsr.res.restrictions       = 0;
}

/* ****************************************************************************
*
* ucsrRelease -
*/
void ucsrRelease(ParseData* reqData)
{
  reqData->ucsr.res.release();
}

/* ****************************************************************************
*
* ucsrCheck -
*/
std::string ucsrCheck(ParseData* reqData, ConnectionInfo* ciP)
{
  return reqData->ucsr.res.check(UpdateContextSubscription, ciP->outFormat, "", reqData->errorString, 0);
}

/* ****************************************************************************
*
* ucsrPresent -
*/
void ucsrPresent(ParseData* reqData)
{
  if (!lmTraceIsSet(LmtDump))
    return;

  PRINTF("\n\n");
  reqData->ucsr.res.present("");
}

/* ****************************************************************************
*
* scrParseVector -
*/
#define UCS   "/updateContextSubscriptionRequest"
#define RS    "/restriction"
#define SC    "/scope"
#define OSC   "/operationScope"
#define SVAL  "/scopeValue"
#define CRC   "/circle"
#define POL   "/polygon"
#define VXL   "/vertexList"
#define VX    "/vertex"
#define NCL   "/notifyConditions"
#define NC    "/notifyCondition"
#define CVL   "/condValueList"

XmlNode ucsrParseVector[] =
{
  { "/updateContextSubscriptionRequest",         nullTreat                   },

  { UCS "/duration",                             duration                    },

  { UCS "/restriction",                          restriction                 },
  { UCS RS "/attributeExpression",               attributeExpression         },
  { UCS RS "/scope",                             nullTreat                   },
  { UCS RS SC "/operationScope",                 operationScope              },
  { UCS RS SC OSC "/scopeType",                  scopeType                   },
  { UCS RS SC OSC "/scopeValue",                 scopeValue                  },

  { UCS RS SC OSC SVAL "/circle",                circle                      },
  { UCS RS SC OSC SVAL CRC "/centerLatitude",    circleCenterLatitude        },
  { UCS RS SC OSC SVAL CRC "/centerLongitude",   circleCenterLongitude       },
  { UCS RS SC OSC SVAL CRC "/radius",            circleRadius                },
  { UCS RS SC OSC SVAL CRC "/inverted",          circleInverted              },

  { UCS RS SC OSC SVAL "/polygon",               polygon                     },
  { UCS RS SC OSC SVAL POL "/inverted",          polygonInverted             },
  { UCS RS SC OSC SVAL POL "/vertexList",        polygonVertexList           },
  { UCS RS SC OSC SVAL POL VXL "/vertex",        polygonVertex               },
  { UCS RS SC OSC SVAL POL VXL VX "/latitude",   polygonVertexLatitude       },
  { UCS RS SC OSC SVAL POL VXL VX "/longitude",  polygonVertexLongitude      },

  { UCS "/subscriptionId",                       subscriptionId              },

  { UCS "/notifyConditions",                     nullTreat                   },
  { UCS NCL "/notifyCondition",                  notifyCondition             },
  { UCS NCL NC "/type",                          notifyConditionType         },
  { UCS NCL NC "/condValueList",                 nullTreat                   },
  { UCS NCL NC CVL "/condValue",                 condValue                   },

  { UCS "/throttling",                           throttling                  },

  { "LAST", NULL }
};
<commit_msg>Remove PRINTF macro<commit_after>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* iot_support at tid dot es
*
* Author: Ken Zangelin
*/
#include <stdio.h>
#include <string>

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "common/globals.h"
#include "orionTypes/areas.h"
#include "ngsi10/UpdateContextSubscriptionRequest.h"
#include "xmlParse/XmlNode.h"
#include "xmlParse/xmlParse.h"
#include "xmlParse/xmlUpdateContextSubscriptionRequest.h"

/* ****************************************************************************
*
* restriction -
*/
static int restriction(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a restriction"));
  ++reqData->ucsr.res.restrictions;

  return 0;
}

/* ****************************************************************************
*
* attributeExpression -
*/
static int attributeExpression(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got an attributeExpression: '%s'", node->value()));
  reqData->ucsr.res.restriction.attributeExpression.set(node->value());

  return 0;
}

/* ****************************************************************************
*
* operationScope -
*/
static int operationScope(xml_node<>* node, ParseData* reqData)
{
  Scope* newScopeP = new Scope();

  LM_T(LmtParse, ("Got an operationScope"));
  reqData->ucsr.scopeP = newScopeP;
  reqData->ucsr.res.restriction.scopeVector.push_back(reqData->ucsr.scopeP);

  return 0;
}

/* ****************************************************************************
*
* scopeType -
*/
static int scopeType(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a scopeType: '%s'", node->value()));
  reqData->ucsr.scopeP->type = node->value();
  return 0;
}

/* ****************************************************************************
*
* scopeValue -
*/
static int scopeValue(xml_node<>* node, ParseData* reqData)
{
  if (reqData->ucsr.scopeP->type == FIWARE_LOCATION || reqData->ucsr.scopeP->type == FIWARE_LOCATION)
  {
    //
    // If the scope type is FIWARE_LOCATION (or its deprecated variant), then the value of this scope is stored in 'circle' or 'polygon'.
    // The field 'value' is not used as more complexity is needed.
    // scopeP->value is here set to FIWARE_LOCATION, in an attempt to warn a future use of 'scopeP->value' when
    // instead 'circle' or 'polygon' should be used.
    //
    reqData->ucsr.scopeP->value = FIWARE_LOCATION;
    LM_T(LmtParse, ("Preparing scopeValue for '%s'", reqData->ucsr.scopeP->type.c_str()));
  }
  else
  {
    reqData->ucsr.scopeP->value = node->value();
    LM_T(LmtParse, ("Got a scopeValue: '%s' for scopeType '%s'", node->value(), reqData->ucsr.scopeP->type.c_str()));
  }

  return 0;
}

/* ****************************************************************************
*
* circle -
*/
static int circle(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circle"));
  reqData->ucsr.scopeP->areaType = orion::CircleType;
  return 0;
}

/* ****************************************************************************
*
* circleCenterLatitude -
*/
static int circleCenterLatitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circleCenterLatitude: %s", node->value()));
  reqData->ucsr.scopeP->circle.center.latitudeSet(node->value());

  return 0;
}

/* ****************************************************************************
*
* circleCenterLongitude -
*/
static int circleCenterLongitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circleCenterLongitude: %s", node->value()));
  reqData->ucsr.scopeP->circle.center.longitudeSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* circleRadius -
*/
static int circleRadius(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a circleRadius: %s", node->value()));
  reqData->ucsr.scopeP->circle.radiusSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* circleInverted -
*/
static int circleInverted(xml_node<>* node, ParseData* parseDataP)
{
  LM_T(LmtParse, ("Got a circleInverted: %s", node->value()));

  parseDataP->ucsr.scopeP->circle.invertedSet(node->value());

  if (!isTrue(node->value()) && !isFalse(node->value()))
  {
    parseDataP->errorString = std::string("bad string for circle/inverted: /") + node->value() + "/";
    return 1;
  }

  return 0;
}

/* ****************************************************************************
*
* polygon -
*/
static int polygon(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygon"));
  reqData->ucsr.scopeP->areaType = orion::PolygonType;
  return 0;
}

/* ****************************************************************************
*
* polygonInverted -
*/
static int polygonInverted(xml_node<>* node, ParseData* parseDataP)
{
  LM_T(LmtParse, ("Got a polygonInverted: %s", node->value()));

  parseDataP->ucsr.scopeP->polygon.invertedSet(node->value());
  if (!isTrue(node->value()) && !isFalse(node->value()))
  {
    parseDataP->errorString = std::string("bad string for polygon/inverted: /") + node->value() + "/";
    return 1;
  }

  return 0;
}

/* ****************************************************************************
*
* polygonVertexList -
*/
static int polygonVertexList(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertexList"));
  return 0;
}

/* ****************************************************************************
*
* polygonVertex -
*/
static int polygonVertex(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertex - creating new vertex for the vertex list"));
  reqData->ucsr.vertexP = new orion::Point();
  reqData->ucsr.scopeP->polygon.vertexAdd(reqData->ucsr.vertexP);
  // reqData->ucsr.scopeP->polygon.vertexList.push_back(reqData->ucsr.vertexP);
  return 0;
}

/* ****************************************************************************
*
* polygonVertexLatitude -
*/
static int polygonVertexLatitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertexLatitude: %s", node->value()));
  reqData->ucsr.vertexP->latitudeSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* polygonVertexLongitude -
*/
static int polygonVertexLongitude(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a polygonVertexLongitude: %s", node->value()));
  reqData->ucsr.vertexP->longitudeSet(node->value());
  return 0;
}

/* ****************************************************************************
*
* duration -
*/
static int duration(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a duration: '%s'", node->value()));
  reqData->ucsr.res.duration.set(node->value());
  return 0;
}

/* ****************************************************************************
*
* notifyCondition -
*/
static int notifyCondition(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a Notify Condition"));
  reqData->ucsr.notifyConditionP = new NotifyCondition();
  reqData->ucsr.res.notifyConditionVector.push_back(reqData->ucsr.notifyConditionP);
  return 0;
}

/* ****************************************************************************
*
* notifyConditionType -
*/
static int notifyConditionType(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a Notify Condition Type: '%s'", node->value()));
  reqData->ucsr.notifyConditionP->type = node->value();
  return 0;
}

/* ****************************************************************************
*
* condValue -
*/
static int condValue(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a Cond Value: '%s'", node->value()));
  reqData->ucsr.notifyConditionP->condValueList.push_back(node->value());
  return 0;
}

/* ****************************************************************************
*
* subscriptionId -
*/
static int subscriptionId(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a subscriptionId: '%s'", node->value()));
  reqData->ucsr.res.subscriptionId.set(node->value());
  return 0;
}

/* ****************************************************************************
*
* throttling -
*/
static int throttling(xml_node<>* node, ParseData* reqData)
{
  LM_T(LmtParse, ("Got a throttling: '%s'", node->value()));
  reqData->ucsr.res.throttling.set(node->value());
  return 0;
}

/* ****************************************************************************
*
* ucsrInit -
*/
void ucsrInit(ParseData* reqData)
{
  reqData->ucsr.notifyConditionP       = NULL;
  reqData->ucsr.scopeP                 = NULL;
  reqData->ucsr.res.restrictions       = 0;
}

/* ****************************************************************************
*
* ucsrRelease -
*/
void ucsrRelease(ParseData* reqData)
{
  reqData->ucsr.res.release();
}

/* ****************************************************************************
*
* ucsrCheck -
*/
std::string ucsrCheck(ParseData* reqData, ConnectionInfo* ciP)
{
  return reqData->ucsr.res.check(UpdateContextSubscription, ciP->outFormat, "", reqData->errorString, 0);
}

/* ****************************************************************************
*
* ucsrPresent -
*/
void ucsrPresent(ParseData* reqData)
{
  if (!lmTraceIsSet(LmtDump))
    return;

  LM_F(("\n\n"));
  reqData->ucsr.res.present("");
}

/* ****************************************************************************
*
* scrParseVector -
*/
#define UCS   "/updateContextSubscriptionRequest"
#define RS    "/restriction"
#define SC    "/scope"
#define OSC   "/operationScope"
#define SVAL  "/scopeValue"
#define CRC   "/circle"
#define POL   "/polygon"
#define VXL   "/vertexList"
#define VX    "/vertex"
#define NCL   "/notifyConditions"
#define NC    "/notifyCondition"
#define CVL   "/condValueList"

XmlNode ucsrParseVector[] =
{
  { "/updateContextSubscriptionRequest",         nullTreat                   },

  { UCS "/duration",                             duration                    },

  { UCS "/restriction",                          restriction                 },
  { UCS RS "/attributeExpression",               attributeExpression         },
  { UCS RS "/scope",                             nullTreat                   },
  { UCS RS SC "/operationScope",                 operationScope              },
  { UCS RS SC OSC "/scopeType",                  scopeType                   },
  { UCS RS SC OSC "/scopeValue",                 scopeValue                  },

  { UCS RS SC OSC SVAL "/circle",                circle                      },
  { UCS RS SC OSC SVAL CRC "/centerLatitude",    circleCenterLatitude        },
  { UCS RS SC OSC SVAL CRC "/centerLongitude",   circleCenterLongitude       },
  { UCS RS SC OSC SVAL CRC "/radius",            circleRadius                },
  { UCS RS SC OSC SVAL CRC "/inverted",          circleInverted              },

  { UCS RS SC OSC SVAL "/polygon",               polygon                     },
  { UCS RS SC OSC SVAL POL "/inverted",          polygonInverted             },
  { UCS RS SC OSC SVAL POL "/vertexList",        polygonVertexList           },
  { UCS RS SC OSC SVAL POL VXL "/vertex",        polygonVertex               },
  { UCS RS SC OSC SVAL POL VXL VX "/latitude",   polygonVertexLatitude       },
  { UCS RS SC OSC SVAL POL VXL VX "/longitude",  polygonVertexLongitude      },

  { UCS "/subscriptionId",                       subscriptionId              },

  { UCS "/notifyConditions",                     nullTreat                   },
  { UCS NCL "/notifyCondition",                  notifyCondition             },
  { UCS NCL NC "/type",                          notifyConditionType         },
  { UCS NCL NC "/condValueList",                 nullTreat                   },
  { UCS NCL NC CVL "/condValue",                 condValue                   },

  { UCS "/throttling",                           throttling                  },

  { "LAST", NULL }
};
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: xmlEnums.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2005-03-18 10:06:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the License); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBA_XMLENUMS_HXX
#define DBA_XMLENUMS_HXX

#define PROGRESS_BAR_STEP 20

namespace dbaxml
{
    enum XMLDocTokens
    {
        XML_TOK_DOC_AUTOSTYLES,
        XML_TOK_DOC_SETTINGS,
        XML_TOK_DOC_DATABASE,
        XML_TOK_DOC_STYLES
    };
    enum XMLDatabaseToken
    {
        XML_TOK_DATASOURCE,
        XML_TOK_FORMS,
        XML_TOK_REPORTS,
        XML_TOK_QUERIES,
        XML_TOK_TABLES
    };
    enum XMLDataSource
    {
        XML_TOK_CONNECTION_RESOURCE,
        XML_TOK_SUPPRESS_VERSION_COLUMNS,
        XML_TOK_JAVA_DRIVER_CLASS,
        XML_TOK_EXTENSION,
        XML_TOK_IS_FIRST_ROW_HEADER_LINE,
        XML_TOK_SHOW_DELETED,
        XML_TOK_IS_TABLE_NAME_LENGTH_LIMITED,
        XML_TOK_SYSTEM_DRIVER_SETTINGS,
        XML_TOK_ENABLE_SQL92_CHECK,
        XML_TOK_APPEND_TABLE_ALIAS_NAME,
        XML_TOK_PARAMETER_NAME_SUBSTITUTION,
        XML_TOK_IGNORE_DRIVER_PRIVILEGES,
        XML_TOK_BOOLEAN_COMPARISON_MODE,
        XML_TOK_USE_CATALOG,
        XML_TOK_BASE_DN,
        XML_TOK_MAX_ROW_COUNT,
        XML_TOK_LOGIN,
        XML_TOK_TABLE_FILTER,
        XML_TOK_TABLE_TYPE_FILTER,
        XML_TOK_AUTO_INCREMENT,
        XML_TOK_DELIMITER,
        XML_TOK_DATA_SOURCE_SETTINGS,
        XML_TOK_FONT_CHARSET,
        XML_TOK_ENCODING
    };
    enum XMLLogin
    {
        XML_TOK_USER_NAME,
        XML_TOK_IS_PASSWORD_REQUIRED
    };
    enum XMLDataSourceInfo
    {
        XML_TOK_STRING,
        XML_TOK_FIELD,
        XML_TOK_DECIMAL,
        XML_TOK_THOUSAND,
        XML_TOK_ADDITIONAL_COLUMN_STATEMENT,
        XML_TOK_ROW_RETRIEVING_STATEMENT,
        XML_TOK_DATA_SOURCE_SETTING,
        XML_TOK_DATA_SOURCE_SETTING_VALUE,
        XML_TOK_DATA_SOURCE_SETTING_IS_LIST,
        XML_TOK_DATA_SOURCE_SETTING_TYPE,
        XML_TOK_DATA_SOURCE_SETTING_NAME
    };
    enum XMLDocuments
    {
        XML_TOK_COMPONENT,
        XML_TOK_COMPONENT_COLLECTION,
        XML_TOK_QUERY_COLLECTION,
        XML_TOK_QUERY,
        XML_TOK_TABLE,
        XML_TOK_COLUMN
    };
    enum XMLComponent
    {
        XML_TOK_HREF    ,
        XML_TOK_TYPE    ,
        XML_TOK_SHOW    ,
        XML_TOK_ACTUATE ,
        XML_TOK_AS_TEMPLATE ,
        XML_TOK_COMPONENT_NAME
    };
    enum XMLType
    {
        XML_TYPE_FORMS,
        XML_TYPE_REPORTS,
        XML_TYPE_QUERIES,
        XML_TYPE_TABLES
    };
    enum XMLQueryTable
    {
        XML_TOK_QUERY_NAME,
        XML_TOK_COMMAND,
        XML_TOK_ESCAPE_PROCESSING,
        XML_TOK_FILTER_STATEMENT,
        XML_TOK_ORDER_STATEMENT,
        XML_TOK_UPDATE_TABLE,
        XML_TOK_CATALOG_NAME,
        XML_TOK_SCHEMA_NAME,
        XML_TOK_STYLE_NAME,
        XML_TOK_APPLY_FILTER,
        XML_TOK_APPLY_ORDER,
        XML_TOK_COLUMNS
    };
    enum XMLColumn
    {
        XML_TOK_COLUMN_NAME,
        XML_TOK_COLUMN_STYLE_NAME,
        XML_TOK_COLUMN_HELP_MESSAGE,
        XML_TOK_COLUMN_VISIBILITY,
        XML_TOK_COLUMN_DEFAULT_VALUE,
        XML_TOK_COLUMN_TYPE_NAME
    };
// -----------------------------------------------------------------------------
} // namespace dbaxml
// -----------------------------------------------------------------------------
#endif // DBA_XMLENUMS_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.98); FILE MERGED 2005/09/05 17:32:51 rt 1.4.98.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlEnums.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:05:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBA_XMLENUMS_HXX
#define DBA_XMLENUMS_HXX

#define PROGRESS_BAR_STEP 20

namespace dbaxml
{
    enum XMLDocTokens
    {
        XML_TOK_DOC_AUTOSTYLES,
        XML_TOK_DOC_SETTINGS,
        XML_TOK_DOC_DATABASE,
        XML_TOK_DOC_STYLES
    };
    enum XMLDatabaseToken
    {
        XML_TOK_DATASOURCE,
        XML_TOK_FORMS,
        XML_TOK_REPORTS,
        XML_TOK_QUERIES,
        XML_TOK_TABLES
    };
    enum XMLDataSource
    {
        XML_TOK_CONNECTION_RESOURCE,
        XML_TOK_SUPPRESS_VERSION_COLUMNS,
        XML_TOK_JAVA_DRIVER_CLASS,
        XML_TOK_EXTENSION,
        XML_TOK_IS_FIRST_ROW_HEADER_LINE,
        XML_TOK_SHOW_DELETED,
        XML_TOK_IS_TABLE_NAME_LENGTH_LIMITED,
        XML_TOK_SYSTEM_DRIVER_SETTINGS,
        XML_TOK_ENABLE_SQL92_CHECK,
        XML_TOK_APPEND_TABLE_ALIAS_NAME,
        XML_TOK_PARAMETER_NAME_SUBSTITUTION,
        XML_TOK_IGNORE_DRIVER_PRIVILEGES,
        XML_TOK_BOOLEAN_COMPARISON_MODE,
        XML_TOK_USE_CATALOG,
        XML_TOK_BASE_DN,
        XML_TOK_MAX_ROW_COUNT,
        XML_TOK_LOGIN,
        XML_TOK_TABLE_FILTER,
        XML_TOK_TABLE_TYPE_FILTER,
        XML_TOK_AUTO_INCREMENT,
        XML_TOK_DELIMITER,
        XML_TOK_DATA_SOURCE_SETTINGS,
        XML_TOK_FONT_CHARSET,
        XML_TOK_ENCODING
    };
    enum XMLLogin
    {
        XML_TOK_USER_NAME,
        XML_TOK_IS_PASSWORD_REQUIRED
    };
    enum XMLDataSourceInfo
    {
        XML_TOK_STRING,
        XML_TOK_FIELD,
        XML_TOK_DECIMAL,
        XML_TOK_THOUSAND,
        XML_TOK_ADDITIONAL_COLUMN_STATEMENT,
        XML_TOK_ROW_RETRIEVING_STATEMENT,
        XML_TOK_DATA_SOURCE_SETTING,
        XML_TOK_DATA_SOURCE_SETTING_VALUE,
        XML_TOK_DATA_SOURCE_SETTING_IS_LIST,
        XML_TOK_DATA_SOURCE_SETTING_TYPE,
        XML_TOK_DATA_SOURCE_SETTING_NAME
    };
    enum XMLDocuments
    {
        XML_TOK_COMPONENT,
        XML_TOK_COMPONENT_COLLECTION,
        XML_TOK_QUERY_COLLECTION,
        XML_TOK_QUERY,
        XML_TOK_TABLE,
        XML_TOK_COLUMN
    };
    enum XMLComponent
    {
        XML_TOK_HREF    ,
        XML_TOK_TYPE    ,
        XML_TOK_SHOW    ,
        XML_TOK_ACTUATE ,
        XML_TOK_AS_TEMPLATE ,
        XML_TOK_COMPONENT_NAME
    };
    enum XMLType
    {
        XML_TYPE_FORMS,
        XML_TYPE_REPORTS,
        XML_TYPE_QUERIES,
        XML_TYPE_TABLES
    };
    enum XMLQueryTable
    {
        XML_TOK_QUERY_NAME,
        XML_TOK_COMMAND,
        XML_TOK_ESCAPE_PROCESSING,
        XML_TOK_FILTER_STATEMENT,
        XML_TOK_ORDER_STATEMENT,
        XML_TOK_UPDATE_TABLE,
        XML_TOK_CATALOG_NAME,
        XML_TOK_SCHEMA_NAME,
        XML_TOK_STYLE_NAME,
        XML_TOK_APPLY_FILTER,
        XML_TOK_APPLY_ORDER,
        XML_TOK_COLUMNS
    };
    enum XMLColumn
    {
        XML_TOK_COLUMN_NAME,
        XML_TOK_COLUMN_STYLE_NAME,
        XML_TOK_COLUMN_HELP_MESSAGE,
        XML_TOK_COLUMN_VISIBILITY,
        XML_TOK_COLUMN_DEFAULT_VALUE,
        XML_TOK_COLUMN_TYPE_NAME
    };
// -----------------------------------------------------------------------------
} // namespace dbaxml
// -----------------------------------------------------------------------------
#endif // DBA_XMLENUMS_HXX
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbImageSVMClassifier.h"

#include <iostream>
#include "otbCommandLineArgumentParser.h"

// otb basic
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbChangeLabelImageFilter.h"

// itk
#include "itkVariableLengthVector.h"

// Statistic XML Reader
#include "otbStatisticsXMLFileReader.h"

// Shift Scale Vector Image Filter
#include "otbShiftScaleVectorImageFilter.h"

// Classification filter
#include "otbSVMImageClassificationFilter.h"

#include "itkTimeProbe.h"
#include "otbStandardFilterWatcher.h"

#include "otbMultiChannelExtractROI.h"

namespace otb
{

int ImageSVMClassifier::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("ImageSVMClassifier");
  descriptor->SetDescription("Perform SVM classification based a previous computed svm model to an new input image.");
  descriptor->AddOption("InputImage", "A new image to classify",
                        "in", 1, true, ApplicationDescriptor::InputImage);
  descriptor->AddOption("ImageStatistics", "a XML file containing mean and variance of input images used to train svm model.",
                        "is", 1, false, ApplicationDescriptor::FileName);
  descriptor->AddOption("SVMmodel", "Estimated model previously computed",
                        "svm", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("OutputLabeledImage", "Output labeled image",
                        "out", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("ROIStartX", "",
                        "x", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("ROIStartY", "",
                        "y", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("ROISizeX", "",
                        "sx", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("ROISizeY", "",
                        "sy", 1, false, ApplicationDescriptor::Integer);
  return EXIT_SUCCESS;
}

int ImageSVMClassifier::Execute(otb::ApplicationOptionsResult* parseResult)
{

  // Input Image
  typedef float                                    PixelType;
  typedef unsigned char                            LabeledPixelType;
  typedef otb::VectorImage<PixelType, 2>           VectorImageType;
  typedef otb::Image<LabeledPixelType, 2>          LabeledImageType;

  typedef otb::ImageFileReader<VectorImageType>    ReaderType;
  typedef otb::ImageFileWriter<VectorImageType>    WriterType;

  //typedef otb::ExtractROIBase<VectorImageType, VectorImageType>          ExtractROIType;
  typedef otb::MultiChannelExtractROI<PixelType, PixelType>  ExtractROIType;

  // Statistic XML file Reader
  typedef itk::VariableLengthVector<PixelType>                          MeasurementType;
  typedef otb::StatisticsXMLFileReader<MeasurementType>                 StatisticsReader;
  typedef otb::ShiftScaleVectorImageFilter<VectorImageType, VectorImageType>  RescalerType;

  /// Classification typedefs
  typedef otb::SVMImageClassificationFilter<VectorImageType, LabeledImageType>   ClassificationFilterType;
  typedef ClassificationFilterType::Pointer                                      ClassificationFilterPointerType;
  typedef ClassificationFilterType::ModelType                                    ModelType;
  typedef ModelType::Pointer                                                     ModelPointerType;
  typedef otb::ChangeLabelImageFilter<LabeledImageType, VectorImageType>         ChangeLabelFilterType;
  typedef ChangeLabelFilterType::Pointer                                         ChangeLabelFilterPointerType;

  //--------------------------
  // Load input image
  ReaderType::Pointer    reader  = ReaderType::New();
  reader->SetFileName(parseResult->GetParameterString("InputImage"));
  reader->UpdateOutputInformation();

  // Load svm model
  ModelPointerType modelSVM = ModelType::New();
  modelSVM->LoadModel(parseResult->GetParameterString("SVMmodel").c_str());

  //--------------------------
  // Normalize input image (optional)
  StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
  MeasurementType  meanMeasurementVector;
  MeasurementType  varianceMeasurementVector;
  RescalerType::Pointer rescaler = RescalerType::New();

  //--------------------------
  // Classify
  ClassificationFilterPointerType classificationFilter = ClassificationFilterType::New();
  classificationFilter->SetModel(modelSVM);

  // Normalize input image
  if (parseResult->IsOptionPresent("ImageStatistics"))
    {
    // Load input image statistics
    statisticsReader->SetFileName(parseResult->GetParameterString("ImageStatistics"));
    meanMeasurementVector     = statisticsReader->GetStatisticVectorByName("mean");
    varianceMeasurementVector = statisticsReader->GetStatisticVectorByName("variance");
    std::cout << "mean: " << meanMeasurementVector << std::endl;
    std::cout << "variance: " << varianceMeasurementVector << std::endl;
    std::cout << "Shift and scale of the input image !" << std::endl;
    // Rescale vector image
    rescaler->SetScale(varianceMeasurementVector);
    rescaler->SetShift(meanMeasurementVector);
    rescaler->SetInput(reader->GetOutput());

    classificationFilter->SetInput(rescaler->GetOutput());
    }
  else
    {
    std::cout << "no shift and scale" << std::endl;
    classificationFilter->SetInput(reader->GetOutput());
    }

  ChangeLabelFilterPointerType changeLabelFilter = ChangeLabelFilterType::New();
  changeLabelFilter->SetInput(classificationFilter->GetOutput());
  changeLabelFilter->SetNumberOfComponentsPerPixel(3);

  //--------------------------
  // Save labeled Image
  WriterType::Pointer    writer  = WriterType::New();
  writer->SetFileName(parseResult->GetParameterString("OutputLabeledImage"));

  // Extract ROI if needed
  if ( (parseResult->IsOptionPresent("ROIStartX")) &&
       (parseResult->IsOptionPresent("ROIStartY")) &&
       (parseResult->IsOptionPresent("ROISizeX")) &&
       (parseResult->IsOptionPresent("ROISizeY")) )
    {
    ExtractROIType::Pointer extract =  ExtractROIType::New();
    extract->SetInput(changeLabelFilter->GetOutput());

    std::cout << parseResult->GetParameterUInt("ROIStartX") << ", "
              << parseResult->GetParameterUInt("ROIStartY") << ", "
              << parseResult->GetParameterUInt("ROISizeX") << ", "
              << parseResult->GetParameterUInt("ROISizeY") << std::endl;

    extract->SetStartX((unsigned long) parseResult->GetParameterUInt("ROIStartX"));
    extract->SetStartY((unsigned long) parseResult->GetParameterUInt("ROIStartY"));
    extract->SetSizeX((unsigned long) parseResult->GetParameterUInt("ROISizeX"));
    extract->SetSizeY((unsigned long) parseResult->GetParameterUInt("ROISizeY"));

    extract->Update();

    writer->SetInput(extract->GetOutput());
    }
  else
    {
    writer->SetInput(changeLabelFilter->GetOutput());
    }

  writer->Update();

  std::cout<<"Classification done ... "<<std::endl;

  return EXIT_SUCCESS;
}

}
<commit_msg>ENH: add some option and comment about classification chain<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbImageSVMClassifier.h"

#include <iostream>
#include "otbCommandLineArgumentParser.h"

// otb basic
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbChangeLabelImageFilter.h"

// itk
#include "itkVariableLengthVector.h"

// Statistic XML Reader
#include "otbStatisticsXMLFileReader.h"

// Shift Scale Vector Image Filter
#include "otbShiftScaleVectorImageFilter.h"

// Classification filter
#include "otbSVMImageClassificationFilter.h"

#include "itkTimeProbe.h"
#include "otbStandardFilterWatcher.h"

#include "otbMultiChannelExtractROI.h"

namespace otb
{

int ImageSVMClassifier::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("ImageSVMClassifier");
  descriptor->SetDescription("Perform SVM classification based a previous computed svm model to an new input image.");
  descriptor->AddOption("InputImage", "A new image to classify",
                        "in", 1, true, ApplicationDescriptor::InputImage);
  descriptor->AddOption("ImageStatistics", "a XML file containing mean and variance of input images used to train svm model.",
                        "is", 1, false, ApplicationDescriptor::FileName);
  descriptor->AddOption("SVMmodel", "Estimated model previously computed",
                        "svm", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("OutputLabeledImage", "Output labeled image",
                        "out", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("ROIStartX", "Start X of the ROI",
                        "x", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("ROIStartY", "Start Y of the ROI",
                        "y", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("ROISizeX", "Size X of the ROI",
                        "sx", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("ROISizeY", "Size Y of the ROI",
                        "sy", 1, false, ApplicationDescriptor::Integer);
  return EXIT_SUCCESS;
}

int ImageSVMClassifier::Execute(otb::ApplicationOptionsResult* parseResult)
{

  // Input Image
  typedef float                                    PixelType;
  typedef unsigned char                            LabeledPixelType;
  typedef otb::VectorImage<PixelType, 2>           VectorImageType;
  typedef otb::Image<LabeledPixelType, 2>          LabeledImageType;

  typedef otb::ImageFileReader<VectorImageType>    ReaderType;
  typedef otb::ImageFileWriter<VectorImageType>    WriterType;

  //typedef otb::ExtractROIBase<VectorImageType, VectorImageType>          ExtractROIType;
  typedef otb::MultiChannelExtractROI<PixelType, PixelType>  ExtractROIType;

  // Statistic XML file Reader
  typedef itk::VariableLengthVector<PixelType>                          MeasurementType;
  typedef otb::StatisticsXMLFileReader<MeasurementType>                 StatisticsReader;
  typedef otb::ShiftScaleVectorImageFilter<VectorImageType, VectorImageType>  RescalerType;

  /// Classification typedefs
  typedef otb::SVMImageClassificationFilter<VectorImageType, LabeledImageType>   ClassificationFilterType;
  typedef ClassificationFilterType::Pointer                                      ClassificationFilterPointerType;
  typedef ClassificationFilterType::ModelType                                    ModelType;
  typedef ModelType::Pointer                                                     ModelPointerType;
  typedef otb::ChangeLabelImageFilter<LabeledImageType, VectorImageType>         ChangeLabelFilterType;
  typedef ChangeLabelFilterType::Pointer                                         ChangeLabelFilterPointerType;

  //--------------------------
  // Load input image
  ReaderType::Pointer    reader  = ReaderType::New();
  reader->SetFileName(parseResult->GetParameterString("InputImage"));
  reader->UpdateOutputInformation();

  // Load svm model
  ModelPointerType modelSVM = ModelType::New();
  modelSVM->LoadModel(parseResult->GetParameterString("SVMmodel").c_str());

  //--------------------------
  // Normalize input image (optional)
  StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
  MeasurementType  meanMeasurementVector;
  MeasurementType  varianceMeasurementVector;
  RescalerType::Pointer rescaler = RescalerType::New();

  //--------------------------
  // Classify
  ClassificationFilterPointerType classificationFilter = ClassificationFilterType::New();
  classificationFilter->SetModel(modelSVM);

  // Normalize input image
  if (parseResult->IsOptionPresent("ImageStatistics"))
    {
    // Load input image statistics
    statisticsReader->SetFileName(parseResult->GetParameterString("ImageStatistics"));
    meanMeasurementVector     = statisticsReader->GetStatisticVectorByName("mean");
    varianceMeasurementVector = statisticsReader->GetStatisticVectorByName("variance");
    std::cout << "mean: " << meanMeasurementVector << std::endl;
    std::cout << "variance: " << varianceMeasurementVector << std::endl;
    std::cout << "Shift and scale of the input image !" << std::endl;
    // Rescale vector image
    rescaler->SetScale(varianceMeasurementVector);
    rescaler->SetShift(meanMeasurementVector);
    rescaler->SetInput(reader->GetOutput());

    classificationFilter->SetInput(rescaler->GetOutput());
    }
  else
    {
    std::cout << "no shift and scale" << std::endl;
    classificationFilter->SetInput(reader->GetOutput());
    }

  ChangeLabelFilterPointerType changeLabelFilter = ChangeLabelFilterType::New();
  changeLabelFilter->SetInput(classificationFilter->GetOutput());
  changeLabelFilter->SetNumberOfComponentsPerPixel(3);

  //--------------------------
  // Save labeled Image
  WriterType::Pointer    writer  = WriterType::New();
  writer->SetFileName(parseResult->GetParameterString("OutputLabeledImage"));

  // Extract ROI if needed
  if ( (parseResult->IsOptionPresent("ROIStartX")) &&
       (parseResult->IsOptionPresent("ROIStartY")) &&
       (parseResult->IsOptionPresent("ROISizeX")) &&
       (parseResult->IsOptionPresent("ROISizeY")) )
    {
    ExtractROIType::Pointer extract =  ExtractROIType::New();
    extract->SetInput(changeLabelFilter->GetOutput());

    std::cout << parseResult->GetParameterUInt("ROIStartX") << ", "
              << parseResult->GetParameterUInt("ROIStartY") << ", "
              << parseResult->GetParameterUInt("ROISizeX") << ", "
              << parseResult->GetParameterUInt("ROISizeY") << std::endl;

    extract->SetStartX((unsigned long) parseResult->GetParameterUInt("ROIStartX"));
    extract->SetStartY((unsigned long) parseResult->GetParameterUInt("ROIStartY"));
    extract->SetSizeX((unsigned long) parseResult->GetParameterUInt("ROISizeX"));
    extract->SetSizeY((unsigned long) parseResult->GetParameterUInt("ROISizeY"));

    extract->Update();

    writer->SetInput(extract->GetOutput());
    }
  else
    {
    writer->SetInput(changeLabelFilter->GetOutput());
    }

  writer->Update();

  std::cout<<"Classification done ... "<<std::endl;

  return EXIT_SUCCESS;
}

}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2017 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/server/interface/address.hpp>

#include <cstdint>
#include <functional>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/server/messages/message.hpp>
#include <bitcoin/server/server_node.hpp>
#include <bitcoin/server/utility/fetch_helpers.hpp>

namespace libbitcoin {
namespace server {

using namespace std::placeholders;
using namespace bc::chain;
using namespace bc::wallet;

// v3 eliminates the subscription type, which we map to 'unspecified'.
void address::subscribe2(server_node& node, const message& request,
    send_handler handler)
{
    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, false);
    handler(message(request, error::success));
}

// v3 adds unsubscribe2, which we map to subscription_type 'unsubscribe'.
void address::unsubscribe2(server_node& node, const message& request,
    send_handler handler)
{
    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, true);
    handler(message(request, error::success));
}

bool address::unwrap_subscribe2_args(binary& prefix_filter,
    const message& request)
{
    // [ prefix_bitsize:1 ]
    // [ prefix_blocks:...]
    const auto& data = request.data();

    if (data.empty())
        return false;

    // First byte is the number of bits.
    auto bit_length = data[0];

    //// The max byte value is 255, so this is unnecessary.
    ////static constexpr size_t address_bits = hash_size * byte_bits;
    ////if (bit_length > address_bits)
    ////    return false;

    // Convert the bit length to byte length.
    const auto byte_length = binary::blocks_size(bit_length);

    if (data.size() - 1 != byte_length)
        return false;

    const data_chunk bytes({ data.begin() + 1, data.end() });
    prefix_filter = binary(bit_length, bytes);
    return true;
}

} // namespace server
} // namespace libbitcoin
<commit_msg>Remove dead comments.<commit_after>/**
 * Copyright (c) 2011-2017 libbitcoin developers (see AUTHORS)
 *
 * This file is part of libbitcoin.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <bitcoin/server/interface/address.hpp>

#include <cstdint>
#include <functional>
#include <bitcoin/bitcoin.hpp>
#include <bitcoin/server/messages/message.hpp>
#include <bitcoin/server/server_node.hpp>
#include <bitcoin/server/utility/fetch_helpers.hpp>

namespace libbitcoin {
namespace server {

using namespace std::placeholders;
using namespace bc::chain;
using namespace bc::wallet;

void address::subscribe2(server_node& node, const message& request,
    send_handler handler)
{
    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, false);
    handler(message(request, error::success));
}

void address::unsubscribe2(server_node& node, const message& request,
    send_handler handler)
{
    binary prefix_filter;

    if (!unwrap_subscribe2_args(prefix_filter, request))
    {
        handler(message(request, error::bad_stream));
        return;
    }

    node.subscribe_address(request.route(), request.id(), prefix_filter, true);
    handler(message(request, error::success));
}

bool address::unwrap_subscribe2_args(binary& prefix_filter,
    const message& request)
{
    // [ prefix_bitsize:1 ]
    // [ prefix_blocks:...]
    const auto& data = request.data();

    if (data.empty())
        return false;

    // First byte is the number of bits.
    auto bit_length = data[0];

    //// The max byte value is 255, so this is unnecessary.
    ////static constexpr size_t address_bits = hash_size * byte_bits;
    ////if (bit_length > address_bits)
    ////    return false;

    // Convert the bit length to byte length.
    const auto byte_length = binary::blocks_size(bit_length);

    if (data.size() - 1 != byte_length)
        return false;

    const data_chunk bytes({ data.begin() + 1, data.end() });
    prefix_filter = binary(bit_length, bytes);
    return true;
}

} // namespace server
} // namespace libbitcoin
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkSplineVtkMapper3D.h"
#include <vtkProp.h>
#include <vtkPropAssembly.h>
#include <vtkCardinalSpline.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkTubeFilter.h>
#include <vtkPropCollection.h>
#include <mitkProperties.h>
#include <mitkPointSet.h>

mitk::SplineVtkMapper3D::SplineVtkMapper3D()
: m_SplinesAvailable (false), m_SplinesAddedToAssembly(false)
{
  m_SplinesActor = vtkActor::New();
  m_SplineAssembly = vtkPropAssembly::New();
  m_SplineResolution = 500;
}

mitk::SplineVtkMapper3D::~SplineVtkMapper3D()
{
  m_SplinesActor->Delete();
  m_SplineAssembly->Delete();
}

vtkProp*
mitk::SplineVtkMapper3D::GetProp()
{
  if (GetDataTreeNode() == NULL)
    return NULL;

  //to assign User Transforms in superclass
  Superclass::GetProp();

  m_SplinesActor->SetUserTransform( GetDataTreeNode()->GetVtkTransform() );

  return m_SplineAssembly;
}

void
mitk::SplineVtkMapper3D::GenerateData()
{
  Superclass::GenerateData();

  // only update spline if UpdateSpline has not been called from
  // external, e.g. by the SplineMapper2D.
  if ( m_SplineUpdateTime < m_LastUpdateTime )
  {
    UpdateSpline();
    this->ApplyProperties();
  }

  if ( m_SplinesAvailable )
  {
    if ( ! m_SplinesAddedToAssembly )
    {
      m_SplineAssembly->AddPart( m_SplinesActor );
      m_SplinesAddedToAssembly = true;
    }
  }
  else
  {
    if ( m_SplinesAddedToAssembly )
    {
      m_SplineAssembly->RemovePart( m_SplinesActor );
      m_SplinesAddedToAssembly = false;
    }
  }
}

void mitk::SplineVtkMapper3D::GenerateData( mitk::BaseRenderer* renderer )
{
  if ( IsVisible( renderer ) == false )
  {
    m_SplinesActor->VisibilityOff();
    m_SplineAssembly->VisibilityOff();
  }
  else
  {
    m_SplinesActor->VisibilityOn();
    m_SplineAssembly->VisibilityOn();

    //remove the PointsAssembly if it was added insuperclass. No need to display points and spline!
    if(m_SplineAssembly->GetParts()->IsItemPresent(m_PointsAssembly))
      m_SplineAssembly->RemovePart(m_PointsAssembly);
    this->ApplyProperties();

  }
}

void mitk::SplineVtkMapper3D::ApplyProperties()
{
//todo: only call if needed and properties have been changed!!!

  //vtk changed the type of rgba during releases. Due to that, the following convert is done
  vtkFloatingPointType rgba[ 4 ] = {1.0f, 1.0f, 1.0f, 1.0f};//white

  //getting the color from DataTreeNode
  float temprgba[4];
  this->GetDataTreeNode()->GetColor( &temprgba[0], NULL );
  //convert to rgba, what ever type it has!
  rgba[0] = temprgba[0];    rgba[1] = temprgba[1];    rgba[2] = temprgba[2];    rgba[3] = temprgba[3];
  //finaly set the color inside the actor
  m_SplinesActor->GetProperty()->SetColor( rgba );

  float lineWidth;
  if (dynamic_cast<mitk::FloatProperty *>(this->GetDataTreeNode()->GetProperty("linewidth").GetPointer()) == NULL)
    lineWidth = 1.0;
  else
    lineWidth = dynamic_cast<mitk::FloatProperty *>(this->GetDataTreeNode()->GetProperty("linewidth").GetPointer())->GetValue();
  m_SplinesActor->GetProperty()->SetLineWidth(lineWidth);
}

bool mitk::SplineVtkMapper3D::SplinesAreAvailable()
{
  return m_SplinesAvailable;
}

vtkPolyData* mitk::SplineVtkMapper3D::GetSplinesPolyData()
{
  if ( m_SplinesAvailable )
    return ( dynamic_cast<vtkPolyDataMapper*>( m_SplinesActor->GetMapper() ) )->GetInput();
  else
    return NULL;
}

vtkActor* mitk::SplineVtkMapper3D::GetSplinesActor()
{
  if ( m_SplinesAvailable )
    return m_SplinesActor;
  else
    return vtkActor::New();
}

unsigned long mitk::SplineVtkMapper3D::GetLastUpdateTime() const
{
  return m_LastUpdateTime.GetMTime();
}

void mitk::SplineVtkMapper3D::UpdateSpline()
{
  mitk::PointSet::Pointer input = const_cast<mitk::PointSet*>( this->GetInput( ) );
//  input->Update();//already done in superclass

  // Number of points on the spline
  unsigned int numberOfOutputPoints = m_SplineResolution;
  unsigned int numberOfInputPoints = input->GetSize();

  if ( numberOfInputPoints >= 2 )
  {
    m_SplinesAvailable = true;
    vtkCardinalSpline* splineX = vtkCardinalSpline::New();
    vtkCardinalSpline* splineY = vtkCardinalSpline::New();
    vtkCardinalSpline* splineZ = vtkCardinalSpline::New();
    unsigned int index = 0;
    mitk::PointSet::DataType::PointsContainer::Pointer pointsContainer = input->GetPointSet()->GetPoints();
    for ( mitk::PointSet::DataType::PointsContainer::Iterator it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++index )
    //for ( unsigned int i = 0 ; i < numberOfInputPoints; ++i )
    {
      mitk::PointSet::PointType point = it->Value();
      splineX->AddPoint( index, point[ 0 ] );
      splineY->AddPoint( index, point[ 1 ] );
      splineZ->AddPoint( index, point[ 2 ] );
    }
    vtkPoints* points = vtkPoints::New();
    vtkPolyData* profileData = vtkPolyData::New();

    // Interpolate x, y and z by using the three spline filters and
    // create new points
    double t = 0.0f;
    for ( unsigned int i = 0; i < numberOfOutputPoints; ++i )
    {
      t = ( ( ( ( double ) numberOfInputPoints ) - 1.0f ) / ( ( ( double ) numberOfOutputPoints ) - 1.0f ) ) * ( ( double ) i );
      points->InsertPoint( i, splineX->Evaluate( t ), splineY->Evaluate( t ), splineZ->Evaluate( t ) ) ;
    }

    // Create the polyline.
    vtkCellArray* lines = vtkCellArray::New();
    lines->InsertNextCell( numberOfOutputPoints );
    for ( unsigned int i = 0; i < numberOfOutputPoints; ++i )
      lines->InsertCellPoint( i );

    profileData->SetPoints( points );
    profileData->SetLines( lines );

    // Add thickness to the resulting line.
    //vtkTubeFilter* profileTubes = vtkTubeFilter::New();
    //profileTubes->SetNumberOfSides(8);
    //profileTubes->SetInput(profileData);
    //profileTubes->SetRadius(.005);

    vtkPolyDataMapper* profileMapper = vtkPolyDataMapper::New();
    profileMapper->SetInput( profileData );

    m_SplinesActor->SetMapper( profileMapper );
  }
  else
  {
    m_SplinesAvailable = false;
  }
  m_SplineUpdateTime.Modified();
}

<commit_msg>ENH: Enormous performance enhancement! only on first time and after a change the spline is build up. And properties are also only applied after a change.<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkSplineVtkMapper3D.h"
#include <vtkProp.h>
#include <vtkPropAssembly.h>
#include <vtkCardinalSpline.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkTubeFilter.h>
#include <vtkPropCollection.h>
#include <mitkProperties.h>
#include <mitkPointSet.h>

mitk::SplineVtkMapper3D::SplineVtkMapper3D()
: m_SplinesAvailable (false), m_SplinesAddedToAssembly(false)
{
  m_SplinesActor = vtkActor::New();
  m_SplineAssembly = vtkPropAssembly::New();
  m_SplineResolution = 500;
}

mitk::SplineVtkMapper3D::~SplineVtkMapper3D()
{
  m_SplinesActor->Delete();
  m_SplineAssembly->Delete();
}

vtkProp*
mitk::SplineVtkMapper3D::GetProp()
{
  if (GetDataTreeNode() == NULL)
    return NULL;

  //to assign User Transforms in superclass
  Superclass::GetProp();

  m_SplinesActor->SetUserTransform( GetDataTreeNode()->GetVtkTransform() );

  return m_SplineAssembly;
}

void
mitk::SplineVtkMapper3D::GenerateData()
{
  Superclass::GenerateData();

  // only update spline if UpdateSpline has not been called from
  // external, e.g. by the SplineMapper2D. But call it the first time when m_SplineUpdateTime = 0 and m_LastUpdateTime = 0.
  if ( m_SplineUpdateTime < m_LastUpdateTime || m_SplineUpdateTime == 0)
  {
    this->UpdateSpline();
    this->ApplyProperties();
  }

  if ( m_SplinesAvailable )
  {
    if ( ! m_SplinesAddedToAssembly )
    {
      m_SplineAssembly->AddPart( m_SplinesActor );
      m_SplinesAddedToAssembly = true;
    }
  }
  else
  {
    if ( m_SplinesAddedToAssembly )
    {
      m_SplineAssembly->RemovePart( m_SplinesActor );
      m_SplinesAddedToAssembly = false;
    }
  }
}

void mitk::SplineVtkMapper3D::GenerateData( mitk::BaseRenderer* renderer )
{
  if ( IsVisible( renderer ) == false )
  {
    m_SplinesActor->VisibilityOff();
    m_SplineAssembly->VisibilityOff();
  }
  else
  {
    m_SplinesActor->VisibilityOn();
    m_SplineAssembly->VisibilityOn();

    //remove the PointsAssembly if it was added in superclass. No need to display points and spline!
    if(m_SplineAssembly->GetParts()->IsItemPresent(m_PointsAssembly))
      m_SplineAssembly->RemovePart(m_PointsAssembly);
  }
}

void mitk::SplineVtkMapper3D::ApplyProperties()
{
//todo: only call if needed and properties have been changed!!!

  //vtk changed the type of rgba during releases. Due to that, the following convert is done
  vtkFloatingPointType rgba[ 4 ] = {1.0f, 1.0f, 1.0f, 1.0f};//white

  //getting the color from DataTreeNode
  float temprgba[4];
  this->GetDataTreeNode()->GetColor( &temprgba[0], NULL );
  //convert to rgba, what ever type it has!
  rgba[0] = temprgba[0];    rgba[1] = temprgba[1];    rgba[2] = temprgba[2];    rgba[3] = temprgba[3];
  //finaly set the color inside the actor
  m_SplinesActor->GetProperty()->SetColor( rgba );

  float lineWidth;
  if (dynamic_cast<mitk::FloatProperty *>(this->GetDataTreeNode()->GetProperty("linewidth").GetPointer()) == NULL)
    lineWidth = 1.0;
  else
    lineWidth = dynamic_cast<mitk::FloatProperty *>(this->GetDataTreeNode()->GetProperty("linewidth").GetPointer())->GetValue();
  m_SplinesActor->GetProperty()->SetLineWidth(lineWidth);
}

bool mitk::SplineVtkMapper3D::SplinesAreAvailable()
{
  return m_SplinesAvailable;
}

vtkPolyData* mitk::SplineVtkMapper3D::GetSplinesPolyData()
{
  if ( m_SplinesAvailable )
    return ( dynamic_cast<vtkPolyDataMapper*>( m_SplinesActor->GetMapper() ) )->GetInput();
  else
    return NULL;
}

vtkActor* mitk::SplineVtkMapper3D::GetSplinesActor()
{
  if ( m_SplinesAvailable )
    return m_SplinesActor;
  else
    return vtkActor::New();
}

unsigned long mitk::SplineVtkMapper3D::GetLastUpdateTime() const
{
  return m_LastUpdateTime.GetMTime();
}

void mitk::SplineVtkMapper3D::UpdateSpline()
{
  mitk::PointSet::Pointer input = const_cast<mitk::PointSet*>( this->GetInput( ) );
//  input->Update();//already done in superclass

  // Number of points on the spline
  unsigned int numberOfOutputPoints = m_SplineResolution;
  unsigned int numberOfInputPoints = input->GetSize();

  if ( numberOfInputPoints >= 2 )
  {
    m_SplinesAvailable = true;
    vtkCardinalSpline* splineX = vtkCardinalSpline::New();
    vtkCardinalSpline* splineY = vtkCardinalSpline::New();
    vtkCardinalSpline* splineZ = vtkCardinalSpline::New();
    unsigned int index = 0;
    mitk::PointSet::DataType::PointsContainer::Pointer pointsContainer = input->GetPointSet()->GetPoints();
    for ( mitk::PointSet::DataType::PointsContainer::Iterator it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++index )
    //for ( unsigned int i = 0 ; i < numberOfInputPoints; ++i )
    {
      mitk::PointSet::PointType point = it->Value();
      splineX->AddPoint( index, point[ 0 ] );
      splineY->AddPoint( index, point[ 1 ] );
      splineZ->AddPoint( index, point[ 2 ] );
    }
    vtkPoints* points = vtkPoints::New();
    vtkPolyData* profileData = vtkPolyData::New();

    // Interpolate x, y and z by using the three spline filters and
    // create new points
    double t = 0.0f;
    for ( unsigned int i = 0; i < numberOfOutputPoints; ++i )
    {
      t = ( ( ( ( double ) numberOfInputPoints ) - 1.0f ) / ( ( ( double ) numberOfOutputPoints ) - 1.0f ) ) * ( ( double ) i );
      points->InsertPoint( i, splineX->Evaluate( t ), splineY->Evaluate( t ), splineZ->Evaluate( t ) ) ;
    }

    // Create the polyline.
    vtkCellArray* lines = vtkCellArray::New();
    lines->InsertNextCell( numberOfOutputPoints );
    for ( unsigned int i = 0; i < numberOfOutputPoints; ++i )
      lines->InsertCellPoint( i );

    profileData->SetPoints( points );
    profileData->SetLines( lines );

    // Add thickness to the resulting line.
    //vtkTubeFilter* profileTubes = vtkTubeFilter::New();
    //profileTubes->SetNumberOfSides(8);
    //profileTubes->SetInput(profileData);
    //profileTubes->SetRadius(.005);

    vtkPolyDataMapper* profileMapper = vtkPolyDataMapper::New();
    profileMapper->SetInput( profileData );

    m_SplinesActor->SetMapper( profileMapper );
  }
  else
  {
    m_SplinesAvailable = false;
  }
  m_SplineUpdateTime.Modified();
}

<|endoftext|>


<commit_before>#include "config.h"

Config::instance = new Config;

static Config* Config::getHandle() {
	return instance;
}

void Config::setMainConfigFile(const std::string& configFileName) {
	if (confname.empty())
		confname = configFileName;
}

void Config::readConfig() {
	config.clear();
	config = readConfig(confname, std::ifstream(confname));
	for (auto callback : notifyList)
		callback();
}

enum ConfigState { CONFIG_BLOCK, CONFIG_KEY, CONFIG_VALUE, CONFIG_VALUE_NEXT, CONFIG_VALUE_VAR, CONFIG_VALUE_STR, CONFIG_VALUE_STR_ESCAPED };
// This enum is simply an implementation detail for the configuration parser; hence it is placed here instead of the header file.

std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>> Config::readConfig(const std::string& filename, std::istream&& configData) {
	ConfigState state = CONFIG_BLOCK;
	unsigned int lineNum = 1;
	LogManager* logger = LogManager::getHandle();
	std::string blockName, key, value, valueVar;
	std::unordered_map<std::string, std::string> blockValues;
	std::unordered_multimap<std::string, std::string> localConfig;
	while (configData.good()) {
		char nextChar = configData.get();
		if (nextChar == std::istream::traits_type::eof())
			break;
		if (nextChar == '\n')
			lineNum++;
		if (state == CONFIG_BLOCK) {
			if (nextChar == '{') {
				if (blockName.empty())
					throw ConfigError (filename, lineNum, "A block without a name was opened.");
				state = CONFIG_KEY;
			} else if (nextChar == '}')
				throw ConfigError (filename, lineNum, "A closing brace could not be mached to an open block.");
			else if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar != ' ' && nextChar != '\t' && nextChar != '\r' && nextChar != '\n')
				blockName += nextChar;
		} else if (state == CONFIG_KEY) {
			if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar == '{')
				throw ConfigError (filename, lineNum, "A block was opened inside another block.");
			else if (nextChar == '}') {
				if (blockValues.empty())
					throw ConfigError (filename, lineNum, "An empty block was defined.  What was the point of that?");
				if (!key.empty() || !value.empty())
					throw ConfigError (filename, lineNum, "A key-value pair was unfinished when the block was terminated.");
				localConfig.insert(std::pair<std::string, std::unordered_map<std::string, std::string>> (blockName, blockValues));
				blockName.clear();
				blockValues.clear();
				logger->log(LOG_ALL, "config", "Block " + blockName + " read.");
				state = CONFIG_BLOCK;
			} else if (nextChar == ';')
				throw ConfigError (filename, lineNum, "A key was specified without a value.");
			else if (nextChar == '=')
				state = CONFIG_VALUE_NEXT;
			else if (nextChar != ' ' && nextChar != '\t' && nextChar != '\r' && nextChar != '\n')
				key += nextChar;
		} else if (state == CONFIG_VALUE) {
			if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar == ';') {
				blockValues.insert(std::pair<std::string, std::string> (key, value));
				key.clear();
				value.clear();
				state = CONFIG_KEY;
			} else if (nextChar == '+')
				state = CONFIG_VALUE_NEXT;
			else
				throw ConfigError (filename, lineNum, "An unexpected character was encountered; expected ';' or '+' (perhaps you forgot to end or properly concatenate your value?).");
		} else if (state == CONFIG_VALUE_NEXT) {
			if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar == '"')
				state = CONFIG_VALUE_STR;
			else if (nextChar != ' ' && nextChar != '\t' && nextChar != '\r' && nextChar != '\n') {
				valueVar += nextChar;
				state = CONFIG_VALUE_VAR;
			}
		} else if (state == CONFIG_VALUE_VAR) {
			if (nextChar == '"')
				throw ConfigError (filename, lineNum, "A string value was specified in the middle of a variable (perhaps you forgot to properly concatenate with '+'?).");
			else if (nextChar == '{')
				throw ConfigError (filename, lineNum, "A block was opened inside another block.");
			else if (nextChar == '}')
				throw ConfigError (filename, lineNum, "A key-value pair was unfinished when the block was terminated.");
			else if (nextChar == ' ' || nextChar == '\t' || nextChar == '\r' || nextChar == '\n' || nextChar == '+' || nextChar == ';') {
				auto keyIter = blockValues.find(valueVar);
				if (keyIter == blockValues.end())
					throw ConfigError (filename, lineNum, "The variable " + valueVar + " was specified, but did not match a variable already specified in the block.");
				value += keyIter->second;
				valueVar.clear();
				if (nextChar == ';') {
					state = CONFIG_KEY;
					blockValues.insert(std::pair<std::string, std::string> (key, value));
					key.clear();
					value.clear();
				} else if (nextChar == '+')
					state = CONFIG_VALUE_NEXT;
				else
					state = CONFIG_VALUE;
			} else
				valueVar += nextChar;
		} else if (state == CONFIG_VALUE_STR) {
			if (nextChar == '\\')
				state = CONFIG_VALUE_STR_ESCAPED;
			else if (nextChar == '"')
				state = CONFIG_VALUE;
			else
				value += nextChar;
		} else if (state == CONFIG_VALUE_STR_ESCAPED) {
			if (nextChar == '\\')
				value += '\\';
			else if (nextChar == 'n')
				value += '\n';
			else if (nextChar == 't')
				value += '\t';
			else if (nextChar == 'r')
				value += '\r';
			else
				value += nextChar;
			state = CONFIG_VALUE_STR;
		}
	}
	if (!blockValues.empty())
		throw ConfigError (filename, lineNum, "A block remained unterminated at the end of the file.");
	std::list<std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>> includedConfigs;
	for (auto block : localConfig) {
		if (block.first == "include") {
			auto inclfIter = block.second.find("file");
			if (inclfIter != block.second.end()) {
				std::string name = inclfIter->second;
				logger->log(LOG_ALL, "config", "Reading included file " + inclfIter->second);
				includedConfigs.push_back(readConfig(inclfIter->second, std::ifstream(name)));
			} else {
				auto incleIter = block.second.find("executable");
				if (incleIter != block.second.end()) {
					std::string cmd = incleIter->second;
					logger->log(LOG_ALL, "config", "Getting configuration data from `" + incleIter->second + "`");
					FILE* pipe = popen(cmd, "r");
					if (!pipe)
						raise ConfigError (cmd, 0, "Could not open pipe to read output.");
					char buffer[256];
					std::stringstream output;
					while (!feof(pipe)) {
						if (fgets(buffer, 256, pipe) != NULL)
							output << buffer;
					}
					pclose(pipe);
					includedConfigs.push_back(readConfig(cmd, output));
				} else
					throw ConfigError (filename, lineNum, "An include block was present that contained neither a file nor an executable.");
			}
		}
	}
	for (auto includes : includedConfigs) {
		for (auto conf : includes.second)
			localConfig.insert(std::pair<std::string, std::unordered_map<std::string, std::string>> (conf));
	}
	return localConfig;
}

void Config::addRehashNotify(std::function<void()> notifyCallback) {
	notifyList.push_back(notifyCallback);
}

size_t Config::blockCount(const std::string& block) const {
	return config.count(block);
}

std::list<std::unordered_map<std::string, std::string>> Config::getBlock(const std::string& block) const {
	std::list<std::unordered_map<std::string, std::string>> blockList;
	std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>::const_iterator startIter, endIter;
	std::tie(startIter, endIter) = config.equal_range(block);
	for (; startIter != endIter; ++startIter)
		blockList.push_back(startIter->second);
	return blockList;
}

std::string Config::getValue(const std::string& block, const std::string& key) const {
	auto blockIter = config.find(block);
	if (blockIter == config.end())
		return "";
	auto dataIter = blockIter->second.find(key);
	if (dataIter == blockIter->second.end())
		return "";
	return dataIter->second;
}

bool Config::getBoolValue(const std::string& block, const std::string& key) const {
	const std::string& value = getValue(block, key);
	std::string lowerValue;
	std::transform(value.begin(), value.end(), std::back_inserter(lowerValue), ::tolower);
	if (lowerValue == "yes" || lowerValue == "on" || lowerValue == "true")
		return true;
	return false;
}

std::list<std::string> Config::getAllValues(const std::string& block, const std::string& key) const {
	std::list<std::string> valueList;
	std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>::const_iterator startIter, endIter;
	std::tie(startIter, endIter) = config.equal_range(block);
	for (; startIter != endIter; ++startIter) {
		auto dataIter = startIter->second.find(key);
		if (dataIter == startIter->second.end())
			valueList.push_back("");
		else
			valueList.push_back(dataIter->second);
	}
	return valueList;
}

std::list<bool> Config::getAllBoolValues(const std::string& block, const std::string& key) const {
	std::list<bool> valueList;
	std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>::const_iterator startIter, endIter;
	std::tie(startIter, endIter) = config.equal_range(block);
	for (std::string lowerValue; startIter != endIter; ++startIter) {
		auto dataIter = startIter->second.find(key);
		if (dataIter == startIter->second.end())
			valueList.push_back(false);
		else {
			lowerValue.clear();
			std::transform(dataIter->second.begin(), dataIter->second.end(), std::back_inserter(lowerValue), ::tolower);
			if (lowerValue == "yes" || lowerValue == "on" || lowerValue == "true")
				valueList.push_back(true);
			else
				valueList.push_back(false);
		}
	}
	return valueList;
}

Config::Config() {}

ConfigError::ConfigError(const std::string& filename, unsigned int lineNum, const std::string& description) {
	std::ostringstream descStr;
	descStr << "An error occurred reading the configuration from '" << filename << "' on line " << lineNum << ": " << description;
	desc = descStr.str();
}<commit_msg>Don't allow a failure in reading the configuration file to result in an empty stored configuration<commit_after>#include "config.h"

Config::instance = new Config;

static Config* Config::getHandle() {
	return instance;
}

void Config::setMainConfigFile(const std::string& configFileName) {
	if (confname.empty())
		confname = configFileName;
}

void Config::readConfig() {
	config = readConfig(confname, std::ifstream(confname));
	for (auto callback : notifyList)
		callback();
}

enum ConfigState { CONFIG_BLOCK, CONFIG_KEY, CONFIG_VALUE, CONFIG_VALUE_NEXT, CONFIG_VALUE_VAR, CONFIG_VALUE_STR, CONFIG_VALUE_STR_ESCAPED };
// This enum is simply an implementation detail for the configuration parser; hence it is placed here instead of the header file.

std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>> Config::readConfig(const std::string& filename, std::istream&& configData) {
	ConfigState state = CONFIG_BLOCK;
	unsigned int lineNum = 1;
	LogManager* logger = LogManager::getHandle();
	std::string blockName, key, value, valueVar;
	std::unordered_map<std::string, std::string> blockValues;
	std::unordered_multimap<std::string, std::string> localConfig;
	while (configData.good()) {
		char nextChar = configData.get();
		if (nextChar == std::istream::traits_type::eof())
			break;
		if (nextChar == '\n')
			lineNum++;
		if (state == CONFIG_BLOCK) {
			if (nextChar == '{') {
				if (blockName.empty())
					throw ConfigError (filename, lineNum, "A block without a name was opened.");
				state = CONFIG_KEY;
			} else if (nextChar == '}')
				throw ConfigError (filename, lineNum, "A closing brace could not be mached to an open block.");
			else if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar != ' ' && nextChar != '\t' && nextChar != '\r' && nextChar != '\n')
				blockName += nextChar;
		} else if (state == CONFIG_KEY) {
			if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar == '{')
				throw ConfigError (filename, lineNum, "A block was opened inside another block.");
			else if (nextChar == '}') {
				if (blockValues.empty())
					throw ConfigError (filename, lineNum, "An empty block was defined.  What was the point of that?");
				if (!key.empty() || !value.empty())
					throw ConfigError (filename, lineNum, "A key-value pair was unfinished when the block was terminated.");
				localConfig.insert(std::pair<std::string, std::unordered_map<std::string, std::string>> (blockName, blockValues));
				blockName.clear();
				blockValues.clear();
				logger->log(LOG_ALL, "config", "Block " + blockName + " read.");
				state = CONFIG_BLOCK;
			} else if (nextChar == ';')
				throw ConfigError (filename, lineNum, "A key was specified without a value.");
			else if (nextChar == '=')
				state = CONFIG_VALUE_NEXT;
			else if (nextChar != ' ' && nextChar != '\t' && nextChar != '\r' && nextChar != '\n')
				key += nextChar;
		} else if (state == CONFIG_VALUE) {
			if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar == ';') {
				blockValues.insert(std::pair<std::string, std::string> (key, value));
				key.clear();
				value.clear();
				state = CONFIG_KEY;
			} else if (nextChar == '+')
				state = CONFIG_VALUE_NEXT;
			else
				throw ConfigError (filename, lineNum, "An unexpected character was encountered; expected ';' or '+' (perhaps you forgot to end or properly concatenate your value?).");
		} else if (state == CONFIG_VALUE_NEXT) {
			if (nextChar == '#') {
				while (configFile.good() && configFile.get() != '\n') {}
				lineNum++;
			} else if (nextChar == '"')
				state = CONFIG_VALUE_STR;
			else if (nextChar != ' ' && nextChar != '\t' && nextChar != '\r' && nextChar != '\n') {
				valueVar += nextChar;
				state = CONFIG_VALUE_VAR;
			}
		} else if (state == CONFIG_VALUE_VAR) {
			if (nextChar == '"')
				throw ConfigError (filename, lineNum, "A string value was specified in the middle of a variable (perhaps you forgot to properly concatenate with '+'?).");
			else if (nextChar == '{')
				throw ConfigError (filename, lineNum, "A block was opened inside another block.");
			else if (nextChar == '}')
				throw ConfigError (filename, lineNum, "A key-value pair was unfinished when the block was terminated.");
			else if (nextChar == ' ' || nextChar == '\t' || nextChar == '\r' || nextChar == '\n' || nextChar == '+' || nextChar == ';') {
				auto keyIter = blockValues.find(valueVar);
				if (keyIter == blockValues.end())
					throw ConfigError (filename, lineNum, "The variable " + valueVar + " was specified, but did not match a variable already specified in the block.");
				value += keyIter->second;
				valueVar.clear();
				if (nextChar == ';') {
					state = CONFIG_KEY;
					blockValues.insert(std::pair<std::string, std::string> (key, value));
					key.clear();
					value.clear();
				} else if (nextChar == '+')
					state = CONFIG_VALUE_NEXT;
				else
					state = CONFIG_VALUE;
			} else
				valueVar += nextChar;
		} else if (state == CONFIG_VALUE_STR) {
			if (nextChar == '\\')
				state = CONFIG_VALUE_STR_ESCAPED;
			else if (nextChar == '"')
				state = CONFIG_VALUE;
			else
				value += nextChar;
		} else if (state == CONFIG_VALUE_STR_ESCAPED) {
			if (nextChar == '\\')
				value += '\\';
			else if (nextChar == 'n')
				value += '\n';
			else if (nextChar == 't')
				value += '\t';
			else if (nextChar == 'r')
				value += '\r';
			else
				value += nextChar;
			state = CONFIG_VALUE_STR;
		}
	}
	if (!blockValues.empty())
		throw ConfigError (filename, lineNum, "A block remained unterminated at the end of the file.");
	std::list<std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>> includedConfigs;
	for (auto block : localConfig) {
		if (block.first == "include") {
			auto inclfIter = block.second.find("file");
			if (inclfIter != block.second.end()) {
				std::string name = inclfIter->second;
				logger->log(LOG_ALL, "config", "Reading included file " + inclfIter->second);
				includedConfigs.push_back(readConfig(inclfIter->second, std::ifstream(name)));
			} else {
				auto incleIter = block.second.find("executable");
				if (incleIter != block.second.end()) {
					std::string cmd = incleIter->second;
					logger->log(LOG_ALL, "config", "Getting configuration data from `" + incleIter->second + "`");
					FILE* pipe = popen(cmd, "r");
					if (!pipe)
						raise ConfigError (cmd, 0, "Could not open pipe to read output.");
					char buffer[256];
					std::stringstream output;
					while (!feof(pipe)) {
						if (fgets(buffer, 256, pipe) != NULL)
							output << buffer;
					}
					pclose(pipe);
					includedConfigs.push_back(readConfig(cmd, output));
				} else
					throw ConfigError (filename, lineNum, "An include block was present that contained neither a file nor an executable.");
			}
		}
	}
	for (auto includes : includedConfigs) {
		for (auto conf : includes.second)
			localConfig.insert(std::pair<std::string, std::unordered_map<std::string, std::string>> (conf));
	}
	return localConfig;
}

void Config::addRehashNotify(std::function<void()> notifyCallback) {
	notifyList.push_back(notifyCallback);
}

size_t Config::blockCount(const std::string& block) const {
	return config.count(block);
}

std::list<std::unordered_map<std::string, std::string>> Config::getBlock(const std::string& block) const {
	std::list<std::unordered_map<std::string, std::string>> blockList;
	std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>::const_iterator startIter, endIter;
	std::tie(startIter, endIter) = config.equal_range(block);
	for (; startIter != endIter; ++startIter)
		blockList.push_back(startIter->second);
	return blockList;
}

std::string Config::getValue(const std::string& block, const std::string& key) const {
	auto blockIter = config.find(block);
	if (blockIter == config.end())
		return "";
	auto dataIter = blockIter->second.find(key);
	if (dataIter == blockIter->second.end())
		return "";
	return dataIter->second;
}

bool Config::getBoolValue(const std::string& block, const std::string& key) const {
	const std::string& value = getValue(block, key);
	std::string lowerValue;
	std::transform(value.begin(), value.end(), std::back_inserter(lowerValue), ::tolower);
	if (lowerValue == "yes" || lowerValue == "on" || lowerValue == "true")
		return true;
	return false;
}

std::list<std::string> Config::getAllValues(const std::string& block, const std::string& key) const {
	std::list<std::string> valueList;
	std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>::const_iterator startIter, endIter;
	std::tie(startIter, endIter) = config.equal_range(block);
	for (; startIter != endIter; ++startIter) {
		auto dataIter = startIter->second.find(key);
		if (dataIter == startIter->second.end())
			valueList.push_back("");
		else
			valueList.push_back(dataIter->second);
	}
	return valueList;
}

std::list<bool> Config::getAllBoolValues(const std::string& block, const std::string& key) const {
	std::list<bool> valueList;
	std::unordered_multimap<std::string, std::unordered_map<std::string, std::string>>::const_iterator startIter, endIter;
	std::tie(startIter, endIter) = config.equal_range(block);
	for (std::string lowerValue; startIter != endIter; ++startIter) {
		auto dataIter = startIter->second.find(key);
		if (dataIter == startIter->second.end())
			valueList.push_back(false);
		else {
			lowerValue.clear();
			std::transform(dataIter->second.begin(), dataIter->second.end(), std::back_inserter(lowerValue), ::tolower);
			if (lowerValue == "yes" || lowerValue == "on" || lowerValue == "true")
				valueList.push_back(true);
			else
				valueList.push_back(false);
		}
	}
	return valueList;
}

Config::Config() {}

ConfigError::ConfigError(const std::string& filename, unsigned int lineNum, const std::string& description) {
	std::ostringstream descStr;
	descStr << "An error occurred reading the configuration from '" << filename << "' on line " << lineNum << ": " << description;
	desc = descStr.str();
}<|endoftext|>