<commit_before>/******************************************************************************\
* File:          otl.cpp
* Purpose:       Implementation of wxExOTL class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2008-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/config.h>
#include <wx/grid.h>
#include <wx/stc/stc.h>
#include <wx/textfile.h> // for wxTextFile::GetEOL()
#include <wx/extension/otl.h>
#include <wx/extension/configdlg.h>
#include <wx/extension/util.h>

#if wxExUSE_OTL

wxExOTL::wxExOTL(const int threaded_mode)
{
  otl_connect::otl_initialize(threaded_mode);
}

wxExOTL::~wxExOTL()
{
  Logoff();
}

bool wxExOTL::Logon(
  wxWindow* parent,
  int max_items,
  const wxString& title)
{
  wxConfigBase* config = wxConfigBase::Get();

  std::vector<wxExConfigItem> v;

  v.push_back(wxExConfigItem(_("Datasource"),
    CONFIG_COMBOBOX,
    wxEmptyString, // page
    true,          // is_required
    max_items));
  v.push_back(wxExConfigItem(_("User")));
  v.push_back(wxExConfigItem(_("Password"), wxEmptyString, wxTE_PASSWORD));

  // Always show the dialog.
  if (wxExConfigDialog(parent,
    v,
    title).ShowModal() == wxID_CANCEL)
  {
    return false;
  }

  try
  {
    const wxString connect =
      config->Read(_("User")) + "/" +
      config->Read(_("Password")) + "@" +
      config->Read(_("Datasource"));

    m_Connect.rlogon(
      connect.c_str(),
      1); // autocommit-flag

    // We cannot use rlogon return value, that is a void.
    return IsConnected();
  }
  catch (otl_exception& p)
  {
    wxLogError("Exception: '%s' while logon to database: %s",
      p.msg,
      config->Read(_("Datasource")).c_str());
  }

  return false;
}

long wxExOTL::Query(const wxString& query)
{
  return otl_cursor::direct_exec(m_Connect, query.c_str());
}

#if wxUSE_GRID
long wxExOTL::Query(
  const wxString& query,
  wxGrid* grid,
  bool& stopped,
  bool empty_results,
  int buffer_size)
{
  wxASSERT(grid != NULL);

  otl_stream i;
  i.set_all_column_types(otl_all_num2str | otl_all_date2str);
  i.open(
    buffer_size,
    query.c_str(),
    m_Connect,
    otl_implicit_select);

  long rows = 0;
  otl_column_desc* desc;

  // Get column names.
  int desc_len;
  desc = i.describe_select(desc_len);

  if (empty_results)
  {
    if (grid->GetNumberCols() > 0)
    {
      grid->DeleteCols(0, grid->GetNumberCols());
    }

    grid->AppendCols(desc_len);

    for (int n = 0; n < desc_len; n++)
    {
      grid->SetColLabelValue(n, desc[n].name);
    }

    if (grid->GetNumberRows() > 0)
    {
      grid->DeleteRows(0, grid->GetNumberRows());
    }
  }

  grid->BeginBatch();

  const long startrow = grid->GetNumberRows();

  // Get all rows.
  while (!i.eof() && !stopped)
  {
    grid->AppendRows();

    for (int n = 0; n < desc_len; n++)
    {
      try
      {
        if (desc[n].otl_var_dbtype == otl_var_varchar_long)
        {
          otl_long_string var;
          i >> var;
          grid->SetCellValue(startrow + rows, n, var.v);
        }
        else
        {
          std::string s;
          i >> s;
          grid->SetCellValue(startrow + rows, n, s);
        }
      }
      catch (otl_exception&)
      {
        // Ignore error.
        grid->SetCellValue(startrow + rows, n, _("<Skipped>"));
      }
    }

    if ((rows & 0xff) == 0)
    {
      wxTheApp->Yield();
    }

    rows++;
  }

  grid->EndBatch();
  grid->AutoSizeColumns();

  return rows;
}
#endif //wxUSE_GRID

long wxExOTL::Query(
  const wxString& query,
  wxStyledTextCtrl* stc,
  bool& stopped,
  int buffer_size)
{
  wxASSERT(stc != NULL);

  otl_stream i;
  i.set_all_column_types(otl_all_num2str | otl_all_date2str);
  i.open(
    buffer_size,
    query.c_str(),
    m_Connect,
    otl_implicit_select);

  stc->AppendText(wxTextFile::GetEOL());

  long rows = 0;
  otl_column_desc* desc;

  // Get column names.
  int desc_len;
  desc = i.describe_select(desc_len);

  for (int n = 0; n < desc_len; n++)
  {
    stc->AppendText(desc[n].name);
    if (n < desc_len - 1) stc->AppendText('\t');
  }

  stc->AppendText(wxTextFile::GetEOL());

  // Get all rows.
  while (!i.eof() && !stopped)
  {
    wxString line;

    for (int n = 0; n < desc_len; n++)
    {
      try
      {
        if (desc[n].otl_var_dbtype == otl_var_varchar_long)
        {
          otl_long_string var;
          i >> var;
          line += var.v;
        }
        else
        {
          std::string s;
          i >> s;
          line += s;
        }
      }
      catch (otl_exception&)
      {
        // Ignore error.
        line += _("<Skipped>");
        line += wxString::Format(" (%d, %d)",
          desc[n].otl_var_dbtype, desc[n].dbsize);
      }

      if (n < desc_len - 1) line += '\t';
    }

    stc->AppendText(line + wxTextFile::GetEOL());

    if ((rows & 0xff) == 0)
    {
      wxTheApp->Yield();
    }

    rows++;
  }

  return rows;
}

const wxString wxExOTL::Version()
{
  const long version = OTL_VERSION_NUMBER;
  return wxString::Format("OTL v%d.%d.%d",
     version >> 16,
    (version >> 8) & 0xff,
    (version & 0xff));
}
#endif // wxExUSE_OTL
<commit_msg>added comment<commit_after>/******************************************************************************\
* File:          otl.cpp
* Purpose:       Implementation of wxExOTL class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2008-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/config.h>
#include <wx/grid.h>
#include <wx/stc/stc.h>
#include <wx/textfile.h> // for wxTextFile::GetEOL()
#include <wx/extension/otl.h>
#include <wx/extension/configdlg.h>
#include <wx/extension/util.h>

#if wxExUSE_OTL

wxExOTL::wxExOTL(const int threaded_mode)
{
  otl_connect::otl_initialize(threaded_mode);
}

wxExOTL::~wxExOTL()
{
  Logoff();
}

bool wxExOTL::Logon(
  wxWindow* parent,
  int max_items,
  const wxString& title)
{
  wxConfigBase* config = wxConfigBase::Get();

  std::vector<wxExConfigItem> v;

  v.push_back(wxExConfigItem(_("Datasource"),
    CONFIG_COMBOBOX,
    wxEmptyString, // page
    true,          // is_required
    max_items));
  v.push_back(wxExConfigItem(_("User")));
  v.push_back(wxExConfigItem(_("Password"), wxEmptyString, wxTE_PASSWORD));

  // Always show the dialog.
  if (wxExConfigDialog(parent,
    v,
    title).ShowModal() == wxID_CANCEL)
  {
    return false;
  }

  try
  {
    const wxString connect =
      config->Read(_("User")) + "/" +
      config->Read(_("Password")) + "@" +
      config->Read(_("Datasource"));

    m_Connect.rlogon(
      connect.c_str(),
      1); // autocommit-flag

    // We cannot use rlogon return value, that is a void.
    return IsConnected();
  }
  catch (otl_exception& p)
  {
    wxLogError("Exception: '%s' while logon to database: %s",
      p.msg,
      config->Read(_("Datasource")).c_str());
  }

  return false;
}

long wxExOTL::Query(const wxString& query)
{
  return otl_cursor::direct_exec(m_Connect, query.c_str());
}

#if wxUSE_GRID
// Cannot be const because of open call.
long wxExOTL::Query(
  const wxString& query,
  wxGrid* grid,
  bool& stopped,
  bool empty_results,
  int buffer_size)
{
  wxASSERT(grid != NULL);

  otl_stream i;
  i.set_all_column_types(otl_all_num2str | otl_all_date2str);
  i.open(
    buffer_size,
    query.c_str(),
    m_Connect,
    otl_implicit_select);

  long rows = 0;
  otl_column_desc* desc;

  // Get column names.
  int desc_len;
  desc = i.describe_select(desc_len);

  if (empty_results)
  {
    if (grid->GetNumberCols() > 0)
    {
      grid->DeleteCols(0, grid->GetNumberCols());
    }

    grid->AppendCols(desc_len);

    for (int n = 0; n < desc_len; n++)
    {
      grid->SetColLabelValue(n, desc[n].name);
    }

    if (grid->GetNumberRows() > 0)
    {
      grid->DeleteRows(0, grid->GetNumberRows());
    }
  }

  grid->BeginBatch();

  const long startrow = grid->GetNumberRows();

  // Get all rows.
  while (!i.eof() && !stopped)
  {
    grid->AppendRows();

    for (int n = 0; n < desc_len; n++)
    {
      try
      {
        if (desc[n].otl_var_dbtype == otl_var_varchar_long)
        {
          otl_long_string var;
          i >> var;
          grid->SetCellValue(startrow + rows, n, var.v);
        }
        else
        {
          std::string s;
          i >> s;
          grid->SetCellValue(startrow + rows, n, s);
        }
      }
      catch (otl_exception&)
      {
        // Ignore error.
        grid->SetCellValue(startrow + rows, n, _("<Skipped>"));
      }
    }

    if ((rows & 0xff) == 0)
    {
      wxTheApp->Yield();
    }

    rows++;
  }

  grid->EndBatch();
  grid->AutoSizeColumns();

  return rows;
}
#endif //wxUSE_GRID

// Cannot be const because of open call.
long wxExOTL::Query(
  const wxString& query,
  wxStyledTextCtrl* stc,
  bool& stopped,
  int buffer_size)
{
  wxASSERT(stc != NULL);

  otl_stream i;
  i.set_all_column_types(otl_all_num2str | otl_all_date2str);
  i.open(
    buffer_size,
    query.c_str(),
    m_Connect,
    otl_implicit_select);

  stc->AppendText(wxTextFile::GetEOL());

  long rows = 0;
  otl_column_desc* desc;

  // Get column names.
  int desc_len;
  desc = i.describe_select(desc_len);

  for (int n = 0; n < desc_len; n++)
  {
    stc->AppendText(desc[n].name);
    if (n < desc_len - 1) stc->AppendText('\t');
  }

  stc->AppendText(wxTextFile::GetEOL());

  // Get all rows.
  while (!i.eof() && !stopped)
  {
    wxString line;

    for (int n = 0; n < desc_len; n++)
    {
      try
      {
        if (desc[n].otl_var_dbtype == otl_var_varchar_long)
        {
          otl_long_string var;
          i >> var;
          line += var.v;
        }
        else
        {
          std::string s;
          i >> s;
          line += s;
        }
      }
      catch (otl_exception&)
      {
        // Ignore error.
        line += _("<Skipped>");
        line += wxString::Format(" (%d, %d)",
          desc[n].otl_var_dbtype, desc[n].dbsize);
      }

      if (n < desc_len - 1) line += '\t';
    }

    stc->AppendText(line + wxTextFile::GetEOL());

    if ((rows & 0xff) == 0)
    {
      wxTheApp->Yield();
    }

    rows++;
  }

  return rows;
}

const wxString wxExOTL::Version()
{
  const long version = OTL_VERSION_NUMBER;

  return wxString::Format("OTL v%d.%d.%d",
     version >> 16,
    (version >> 8) & 0xff,
    (version & 0xff));
}
#endif // wxExUSE_OTL
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2020 Winlin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef SRS_CORE_HPP
#define SRS_CORE_HPP

// The version config.
#define VERSION_MAJOR       3
#define VERSION_MINOR       0
#define SRS3_VERSION_REVISION    111
#define VERSION_REVISION SRS3_VERSION_REVISION

// The macros generated by configure script.
#include <srs_auto_headers.hpp>

// To convert macro values to string.
// @see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
#define SRS_INTERNAL_STR(v) #v
#define SRS_XSTR(v) SRS_INTERNAL_STR(v)

// The project informations, may sent to client in HTTP header or RTMP metadata.
#define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_CODE "OuXuli"
#define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs"
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
#define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION)
#define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY "/" RTMP_SIG_SRS_VERSION "(" RTMP_SIG_SRS_CODE ")"

// The current stable release.
#define VERSION_STABLE 2
#define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE)".0release"

// For 32bit os, 2G big file limit for unistd io,
// ie. read/write/lseek to use 64bits size for huge file.
#ifndef _FILE_OFFSET_BITS
    #define _FILE_OFFSET_BITS 64
#endif

// For int64_t print using PRId64 format.
#ifndef __STDC_FORMAT_MACROS
    #define __STDC_FORMAT_MACROS
#endif

// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <inttypes.h>
#endif

#include <assert.h>
#define srs_assert(expression) assert(expression)

#include <stddef.h>
#include <sys/types.h>

// The time unit for timeout, interval or duration.
#include <srs_core_time.hpp>

// Some important performance options.
#include <srs_core_performance.hpp>

// To free the p and set to NULL.
// @remark The p must be a pointer T*.
#define srs_freep(p) \
    if (p) { \
        delete p; \
        p = NULL; \
    } \
    (void)0
// Please use the freepa(T[]) to free an array, otherwise the behavior is undefined.
#define srs_freepa(pa) \
    if (pa) { \
        delete[] pa; \
        pa = NULL; \
    } \
    (void)0

// For librtmp, it is pure c++ and supports all OS.
#ifndef SRS_EXPORT_LIBRTMP
    // Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm
    // @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1
    #if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__) && !defined(__aarch64__)
        #error "only support i386/amd64/x86_64/arm cpu"
    #endif
#endif

// Error predefined for all modules.
class SrsCplxError;
typedef SrsCplxError* srs_error_t;

#endif
<commit_msg>Update version<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2020 Winlin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef SRS_CORE_HPP
#define SRS_CORE_HPP

// The version config.
#define VERSION_MAJOR       3
#define VERSION_MINOR       0
// Version for SRS3.
#define SRS3_VERSION_REVISION    111
// Version we used.
#define VERSION_REVISION SRS3_VERSION_REVISION

// The macros generated by configure script.
#include <srs_auto_headers.hpp>

// To convert macro values to string.
// @see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
#define SRS_INTERNAL_STR(v) #v
#define SRS_XSTR(v) SRS_INTERNAL_STR(v)

// The project informations, may sent to client in HTTP header or RTMP metadata.
#define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_CODE "OuXuli"
#define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs"
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
#define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION)
#define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY "/" RTMP_SIG_SRS_VERSION "(" RTMP_SIG_SRS_CODE ")"

// The current stable release.
#define VERSION_STABLE 2
#define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE)".0release"

// For 32bit os, 2G big file limit for unistd io,
// ie. read/write/lseek to use 64bits size for huge file.
#ifndef _FILE_OFFSET_BITS
    #define _FILE_OFFSET_BITS 64
#endif

// For int64_t print using PRId64 format.
#ifndef __STDC_FORMAT_MACROS
    #define __STDC_FORMAT_MACROS
#endif

// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <inttypes.h>
#endif

#include <assert.h>
#define srs_assert(expression) assert(expression)

#include <stddef.h>
#include <sys/types.h>

// The time unit for timeout, interval or duration.
#include <srs_core_time.hpp>

// Some important performance options.
#include <srs_core_performance.hpp>

// To free the p and set to NULL.
// @remark The p must be a pointer T*.
#define srs_freep(p) \
    if (p) { \
        delete p; \
        p = NULL; \
    } \
    (void)0
// Please use the freepa(T[]) to free an array, otherwise the behavior is undefined.
#define srs_freepa(pa) \
    if (pa) { \
        delete[] pa; \
        pa = NULL; \
    } \
    (void)0

// For librtmp, it is pure c++ and supports all OS.
#ifndef SRS_EXPORT_LIBRTMP
    // Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm
    // @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1
    #if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__) && !defined(__aarch64__)
        #error "only support i386/amd64/x86_64/arm cpu"
    #endif
#endif

// Error predefined for all modules.
class SrsCplxError;
typedef SrsCplxError* srs_error_t;

#endif
<|endoftext|>


<commit_before>#include <functional>
#include <future>
#include <memory>
#include <functional>
#include "geos/geom/Geometry.h"
#include "geos/util/GEOSException.h"
#include "kernel.h"
#include "coverage.h"
#include "columndefinition.h"
#include "table.h"
#include "attributerecord.h"
#include "feature.h"
#include "featurecoverage.h"
#include "symboltable.h"
#include "OperationExpression.h"
#include "operationmetadata.h"
#include "operation.h"
#include "operationhelper.h"
#include "operationhelperfeatures.h"
#include "geometryhelper.h"
#include "commandhandler.h"
#include "featureiterator.h"
#include "spatialrelation.h"

using namespace Ilwis;
using namespace BaseOperations;

SpatialRelationOperation::SpatialRelationOperation()
{
}

SpatialRelationOperation::SpatialRelationOperation(quint64 metaid, const Ilwis::OperationExpression &expr) : OperationImplementation(metaid, expr)
{

}

quint64 SpatialRelationOperation::createMetadata(OperationResource& operation)
{
    operation.setInParameterCount({2});

    operation.addInParameter(0,itCOVERAGE, TR("coverage"),TR("coverage on which the spatial relation is applicable"));
    operation.addInParameter(1,itSTRING, TR("Geometry"), TR("the geometry for which the spatial relation holds true"));

    operation.setOutParameterCount({1});
    operation.addOutParameter(0,itCOLLECTION | itINTEGER, TR("result index collection"));
    operation.setKeywords("geometry, coordinate, coverage, spatial relation");

    mastercatalog()->addItems({operation});
    return operation.id();

}

bool SpatialRelationOperation::execute(ExecutionContext *ctx, SymbolTable &symTable)
{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx, symTable)) != sPREPARED)
            return false;

    IFeatureCoverage features = _coverage.as<FeatureCoverage>();

    std::set<quint32> resultset;
    int index = 0;
    geos::geom::Geometry *geomRelation = _geometry.get();
    try{
    if ( geomRelation != 0) {
        for(auto& iter : features){
            int geomcount = iter->trackSize();
            for(int gindex = 0; gindex < geomcount; ++gindex){
                for(int gi = 0; gi < geomRelation->getNumGeometries(); ++gi){
                    const geos::geom::Geometry *geomCoverage = iter->geometry(gindex).get();
                    if ( geomCoverage!= 0 &&_relation(geomCoverage,geomRelation->getGeometryN(gi) )){
                        resultset.insert(index);
                    }
                }
            }
            ++index;
        }
    }
    } catch(geos::util::GEOSException& exc){
        ERROR0(QString(exc.what()));
        return false;
    }

    std::vector<quint32> result(resultset.begin(), resultset.end());
    if ( ctx != 0) {
        QVariant value;
        value.setValue<std::vector<quint32>>(result);
        ctx->setOutput(symTable, value, sUNDEF, itINTEGER | itCOLLECTION, Resource());
    }

    return true;
}

OperationImplementation::State SpatialRelationOperation::prepare(ExecutionContext *ctx, const SymbolTable &)
{
    QString fc = _expression.parm(0).value();

    if (!_coverage.prepare(fc)) {
        ERROR2(ERR_COULD_NOT_LOAD_2,fc,"");
        return sPREPAREFAILED;
    }

    QString quotedGeom = _expression.parm(1).value();
    QString geom = quotedGeom.remove('\"');
    _geometry.reset(GeometryHelper::fromWKT(geom));
    if ( !_geometry){
        ERROR2(ERR_NO_INITIALIZED_2, TR("Geometry"), TR("Contains operation"));
        return sPREPAREFAILED;
    }

    return sPREPARED;

}

//---------------------------------------------------------------------------------
REGISTER_OPERATION(Contains)

Contains::Contains(){}

Contains::Contains(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Contains::create(quint64 metaid, const Ilwis::OperationExpression &expr){
    return new Contains(metaid, expr);
}

bool Contains::contains(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomCoverage->contains(geomRelation);
}

OperationImplementation::State Contains::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Contains::contains;
    return sPREPARED;
}

quint64 Contains::createMetadata(){
    OperationResource operation({"ilwis://operations/contains"});
    operation.setSyntax("contains(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the contains constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//----------------------------------------------------------------------------------
REGISTER_OPERATION(Covers)

Covers::Covers(){}

Covers::Covers(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Covers::create(quint64 metaid, const Ilwis::OperationExpression &expr){
    return new Covers(metaid, expr);
}

bool Covers::covers(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomCoverage->covers(geomRelation);
}

OperationImplementation::State Covers::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Covers::covers;
    return sPREPARED;
}

quint64 Covers::createMetadata(){
    OperationResource operation({"ilwis://operations/covers"});
    operation.setSyntax("covers(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the covers constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(CoveredBy)

CoveredBy::CoveredBy(){}

CoveredBy::CoveredBy(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *CoveredBy::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new CoveredBy(metaid, expr);
}

bool CoveredBy::coveredBy(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->coveredBy(geomCoverage);
}

OperationImplementation::State CoveredBy::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = CoveredBy::coveredBy;
    return sPREPARED;
}

quint64 CoveredBy::createMetadata()
{
    OperationResource operation({"ilwis://operations/coveredby"});
    operation.setSyntax("coveredby(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the CoveredBy constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(Touches)

Touches::Touches(){}

Touches::Touches(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Touches::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Touches(metaid, expr);
}

bool Touches::touches(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->touches(geomCoverage);
}

OperationImplementation::State Touches::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Touches::touches;
    return sPREPARED;
}

quint64 Touches::createMetadata()
{
    OperationResource operation({"ilwis://operations/touches"});
    operation.setSyntax("touches(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the Touches constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(Intersects)

Intersects::Intersects(){}

Intersects::Intersects(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Intersects::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Intersects(metaid, expr);
}

bool Intersects::intersects(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->intersects(geomCoverage);
}

OperationImplementation::State Intersects::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Intersects::intersects;
    return sPREPARED;
}

quint64 Intersects::createMetadata()
{
    OperationResource operation({"ilwis://operations/intersects"});
    operation.setSyntax("intersects(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the intersects constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//--------------------------------------------------------------------------------
REGISTER_OPERATION(Disjoint)

Disjoint::Disjoint(){}

Disjoint::Disjoint(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Disjoint::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Disjoint(metaid, expr);
}

bool Disjoint::disjoint(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->disjoint(geomCoverage);
}

OperationImplementation::State Disjoint::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Disjoint::disjoint;
    return sPREPARED;
}

quint64 Disjoint::createMetadata()
{
    OperationResource operation({"ilwis://operations/disjoint"});
    operation.setSyntax("disjoint(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the disjoint constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}

//--------------------------------------------------------------------------------
REGISTER_OPERATION(Within)

Within::Within(){}

Within::Within(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Within::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Within(metaid, expr);
}

bool Within::within(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->within(geomCoverage);
}

OperationImplementation::State Within::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Within::within;
    return sPREPARED;
}

quint64 Within::createMetadata()
{
    OperationResource operation({"ilwis://operations/within"});
    operation.setSyntax("within(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the within constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}

//--------------------------------------------------------------------------------
REGISTER_OPERATION(Equals)

Equals::Equals(){}

Equals::Equals(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Equals::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Equals(metaid, expr);
}

bool Equals::equals(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->equals(geomCoverage);
}

OperationImplementation::State Equals::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Equals::equals;
    return sPREPARED;
}

quint64 Equals::createMetadata()
{
    OperationResource operation({"ilwis://operations/equals"});
    operation.setSyntax("equals(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the equals constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//--------------------------------------------------------------------------------
REGISTER_OPERATION(Crosses)

Crosses::Crosses(){}

Crosses::Crosses(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Crosses::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Crosses(metaid, expr);
}

bool Crosses::crosses(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->crosses(geomCoverage);
}

OperationImplementation::State Crosses::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Crosses::crosses;
    return sPREPARED;
}

quint64 Crosses::createMetadata()
{
    OperationResource operation({"ilwis://operations/crosses"});
    operation.setSyntax("crosses(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the Crosses constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(Overlaps)

Overlaps::Overlaps(){}

Overlaps::Overlaps(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Overlaps::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Overlaps(metaid, expr);
}

bool Overlaps::overlaps(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->overlaps(geomCoverage);
}

OperationImplementation::State Overlaps::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Overlaps::overlaps;
    return sPREPARED;
}

quint64 Overlaps::createMetadata()
{
    OperationResource operation({"ilwis://operations/overlaps"});
    operation.setSyntax("overlaps(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the Overlaps constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
<commit_msg>order of geometries for covers was just the other way around<commit_after>#include <functional>
#include <future>
#include <memory>
#include <functional>
#include "geos/geom/Geometry.h"
#include "geos/util/GEOSException.h"
#include "kernel.h"
#include "coverage.h"
#include "columndefinition.h"
#include "table.h"
#include "attributerecord.h"
#include "feature.h"
#include "featurecoverage.h"
#include "symboltable.h"
#include "OperationExpression.h"
#include "operationmetadata.h"
#include "operation.h"
#include "operationhelper.h"
#include "operationhelperfeatures.h"
#include "geometryhelper.h"
#include "commandhandler.h"
#include "featureiterator.h"
#include "spatialrelation.h"

using namespace Ilwis;
using namespace BaseOperations;

SpatialRelationOperation::SpatialRelationOperation()
{
}

SpatialRelationOperation::SpatialRelationOperation(quint64 metaid, const Ilwis::OperationExpression &expr) : OperationImplementation(metaid, expr)
{

}

quint64 SpatialRelationOperation::createMetadata(OperationResource& operation)
{
    operation.setInParameterCount({2});

    operation.addInParameter(0,itCOVERAGE, TR("coverage"),TR("coverage on which the spatial relation is applicable"));
    operation.addInParameter(1,itSTRING, TR("Geometry"), TR("the geometry for which the spatial relation holds true"));

    operation.setOutParameterCount({1});
    operation.addOutParameter(0,itCOLLECTION | itINTEGER, TR("result index collection"));
    operation.setKeywords("geometry, coordinate, coverage, spatial relation");

    mastercatalog()->addItems({operation});
    return operation.id();

}

bool SpatialRelationOperation::execute(ExecutionContext *ctx, SymbolTable &symTable)
{
    if (_prepState == sNOTPREPARED)
        if((_prepState = prepare(ctx, symTable)) != sPREPARED)
            return false;

    IFeatureCoverage features = _coverage.as<FeatureCoverage>();

    std::set<quint32> resultset;
    int index = 0;
    geos::geom::Geometry *geomRelation = _geometry.get();
    try{
    if ( geomRelation != 0) {
        for(auto& iter : features){
            int geomcount = iter->trackSize();
            for(int gindex = 0; gindex < geomcount; ++gindex){
                for(int gi = 0; gi < geomRelation->getNumGeometries(); ++gi){
                    const geos::geom::Geometry *geomCoverage = iter->geometry(gindex).get();
                    if ( geomCoverage!= 0 &&_relation(geomCoverage,geomRelation->getGeometryN(gi) )){
                        resultset.insert(index);
                    }
                }
            }
            ++index;
        }
    }
    } catch(geos::util::GEOSException& exc){
        ERROR0(QString(exc.what()));
        return false;
    }

    std::vector<quint32> result(resultset.begin(), resultset.end());
    if ( ctx != 0) {
        QVariant value;
        value.setValue<std::vector<quint32>>(result);
        ctx->setOutput(symTable, value, sUNDEF, itINTEGER | itCOLLECTION, Resource());
    }

    return true;
}

OperationImplementation::State SpatialRelationOperation::prepare(ExecutionContext *ctx, const SymbolTable &)
{
    QString fc = _expression.parm(0).value();

    if (!_coverage.prepare(fc)) {
        ERROR2(ERR_COULD_NOT_LOAD_2,fc,"");
        return sPREPAREFAILED;
    }

    QString quotedGeom = _expression.parm(1).value();
    QString geom = quotedGeom.remove('\"');
    _geometry.reset(GeometryHelper::fromWKT(geom));
    if ( !_geometry){
        ERROR2(ERR_NO_INITIALIZED_2, TR("Geometry"), TR("Contains operation"));
        return sPREPAREFAILED;
    }

    return sPREPARED;

}

//---------------------------------------------------------------------------------
REGISTER_OPERATION(Contains)

Contains::Contains(){}

Contains::Contains(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Contains::create(quint64 metaid, const Ilwis::OperationExpression &expr){
    return new Contains(metaid, expr);
}

bool Contains::contains(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomCoverage->contains(geomRelation);
}

OperationImplementation::State Contains::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Contains::contains;
    return sPREPARED;
}

quint64 Contains::createMetadata(){
    OperationResource operation({"ilwis://operations/contains"});
    operation.setSyntax("contains(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the contains constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//----------------------------------------------------------------------------------
REGISTER_OPERATION(Covers)

Covers::Covers(){}

Covers::Covers(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Covers::create(quint64 metaid, const Ilwis::OperationExpression &expr){
    return new Covers(metaid, expr);
}

bool Covers::covers(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return  geomRelation->covers(geomCoverage);
}

OperationImplementation::State Covers::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Covers::covers;
    return sPREPARED;
}

quint64 Covers::createMetadata(){
    OperationResource operation({"ilwis://operations/covers"});
    operation.setSyntax("covers(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the covers constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(CoveredBy)

CoveredBy::CoveredBy(){}

CoveredBy::CoveredBy(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *CoveredBy::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new CoveredBy(metaid, expr);
}

bool CoveredBy::coveredBy(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->coveredBy(geomCoverage);
}

OperationImplementation::State CoveredBy::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = CoveredBy::coveredBy;
    return sPREPARED;
}

quint64 CoveredBy::createMetadata()
{
    OperationResource operation({"ilwis://operations/coveredby"});
    operation.setSyntax("coveredby(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the CoveredBy constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(Touches)

Touches::Touches(){}

Touches::Touches(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Touches::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Touches(metaid, expr);
}

bool Touches::touches(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->touches(geomCoverage);
}

OperationImplementation::State Touches::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Touches::touches;
    return sPREPARED;
}

quint64 Touches::createMetadata()
{
    OperationResource operation({"ilwis://operations/touches"});
    operation.setSyntax("touches(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the Touches constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(Intersects)

Intersects::Intersects(){}

Intersects::Intersects(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Intersects::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Intersects(metaid, expr);
}

bool Intersects::intersects(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->intersects(geomCoverage);
}

OperationImplementation::State Intersects::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Intersects::intersects;
    return sPREPARED;
}

quint64 Intersects::createMetadata()
{
    OperationResource operation({"ilwis://operations/intersects"});
    operation.setSyntax("intersects(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the intersects constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//--------------------------------------------------------------------------------
REGISTER_OPERATION(Disjoint)

Disjoint::Disjoint(){}

Disjoint::Disjoint(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Disjoint::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Disjoint(metaid, expr);
}

bool Disjoint::disjoint(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->disjoint(geomCoverage);
}

OperationImplementation::State Disjoint::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Disjoint::disjoint;
    return sPREPARED;
}

quint64 Disjoint::createMetadata()
{
    OperationResource operation({"ilwis://operations/disjoint"});
    operation.setSyntax("disjoint(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the disjoint constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}

//--------------------------------------------------------------------------------
REGISTER_OPERATION(Within)

Within::Within(){}

Within::Within(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Within::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Within(metaid, expr);
}

bool Within::within(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->within(geomCoverage);
}

OperationImplementation::State Within::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Within::within;
    return sPREPARED;
}

quint64 Within::createMetadata()
{
    OperationResource operation({"ilwis://operations/within"});
    operation.setSyntax("within(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the within constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}

//--------------------------------------------------------------------------------
REGISTER_OPERATION(Equals)

Equals::Equals(){}

Equals::Equals(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Equals::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Equals(metaid, expr);
}

bool Equals::equals(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->equals(geomCoverage);
}

OperationImplementation::State Equals::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Equals::equals;
    return sPREPARED;
}

quint64 Equals::createMetadata()
{
    OperationResource operation({"ilwis://operations/equals"});
    operation.setSyntax("equals(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the equals constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//--------------------------------------------------------------------------------
REGISTER_OPERATION(Crosses)

Crosses::Crosses(){}

Crosses::Crosses(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Crosses::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Crosses(metaid, expr);
}

bool Crosses::crosses(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->crosses(geomCoverage);
}

OperationImplementation::State Crosses::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Crosses::crosses;
    return sPREPARED;
}

quint64 Crosses::createMetadata()
{
    OperationResource operation({"ilwis://operations/crosses"});
    operation.setSyntax("crosses(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the Crosses constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
//-----------------------------------------------------------------------------------
REGISTER_OPERATION(Overlaps)

Overlaps::Overlaps(){}

Overlaps::Overlaps(quint64 metaid, const Ilwis::OperationExpression &expr) : SpatialRelationOperation(metaid, expr){}

Ilwis::OperationImplementation *Overlaps::create(quint64 metaid, const Ilwis::OperationExpression &expr)
{
    return new Overlaps(metaid, expr);
}

bool Overlaps::overlaps(const geos::geom::Geometry *geomCoverage, const geos::geom::Geometry *geomRelation) {
    return geomRelation->overlaps(geomCoverage);
}

OperationImplementation::State Overlaps::prepare(ExecutionContext *ctx, const SymbolTable &sym){
    if (!SpatialRelationOperation::prepare(ctx, sym) == sPREPARED)
        return sPREPAREFAILED;
    _relation = Overlaps::overlaps;
    return sPREPARED;
}

quint64 Overlaps::createMetadata()
{
    OperationResource operation({"ilwis://operations/overlaps"});
    operation.setSyntax("overlaps(coverage,wkt-defintion)");
    operation.setDescription(TR("returns a feature-index of all features that satisfy the Overlaps constraint"));

    return SpatialRelationOperation::createMetadata(operation);
}
<|endoftext|>


<commit_before>#pragma once

#include "Constants.hpp"
#include "Geometry2d/Point.hpp"
#include "time.hpp"

#include <cmath>
#include <deque>
#include <QString>
#include <stdexcept>
#include <stdint.h>
#include <sys/time.h>
#include <typeinfo>
#include <vector>
#include <QtWidgets>

const static bool THROW_DEBUG_EXCEPTIONS = true;

template <class exception>
static inline void debugThrow(const exception &e) {
	if (THROW_DEBUG_EXCEPTIONS) {
		throw e;
	}
}

static inline void debugThrow(const std::string &string) {
	debugThrow(std::runtime_error(string));
}

/**
 * @brief Restricts the given angle to be between pi and -pi
 *
 * @param a An angle in radians
 * @return An equivalent angle in radians restricted to [-pi, pi]
 */
static inline float fixAngleRadians(float a)
{
	a = remainder(a, 2*M_PI);
	while (a < -M_PI) a += 2.0*M_PI;
	while (a > M_PI) a -= 2.0*M_PI;
	return a;
}

/** Checks whether or not the given ball is in the defense area. */
static inline bool ballIsInGoalieBox(Geometry2d::Point point) {
	if (std::abs(point.x) < Field_Dimensions::Current_Dimensions.GoalFlat() / 2.0f) // Ball is in center (rectangular) portion of defensive bubble
	{
		return point.y > 0 && point.y < Field_Dimensions::Current_Dimensions.ArcRadius();
	} else if (std::abs(point.x) < (Field_Dimensions::Current_Dimensions.ArcRadius() + Field_Dimensions::Current_Dimensions.GoalFlat() / 2.0f)) // Ball is in one of the side (arc) portions of defensive bubble
	{
		double adjusted_x = std::abs(point.x) - (Field_Dimensions::Current_Dimensions.GoalFlat() / 2.0f);
		double max_y = sqrt( (Field_Dimensions::Current_Dimensions.ArcRadius() * Field_Dimensions::Current_Dimensions.ArcRadius()) - (adjusted_x * adjusted_x));
		return point.y > 0 && point.y <= max_y;
	}
	return false;
}

static Geometry2d::Point fromOursToTheirs(Geometry2d::Point &pt) {
	Geometry2d::Point c;
	c.y = Field_Dimensions::Current_Dimensions.Length() - pt.y;
	c.x = -pt.x;

	return c;
}

static bool ballIsInTheirGoalieBox(Geometry2d::Point &pt) {
	Geometry2d::Point converted = fromOursToTheirs(pt);
	return ballIsInGoalieBox(converted);
}

/** Returns @value if it is in bounds, otherwise returns the bound it is closest to */
template<class T>
float clamp(T value, T min, T max)
{
	if (value > max)
	{
		return max;
	}
	else if (value < min)
	{
		return min;
	}
	return value;
}

// Removes all entries in a std::map which associate to the given value.
template<class Map_Type, class Data_Type>
void map_remove(Map_Type &map, Data_Type &value)
{
	typename Map_Type::iterator i = map.begin();
	while (i != map.end())
	{
		typename Map_Type::iterator next = i;
		++next;

		if (i->second == value)
		{
			map.erase(i);
		}

		i = next;
	}
}

// If <key> exists in <map>, returns map[key].
// If not, returns 0.
template<typename Map>
typename Map::mapped_type map_lookup(const Map &map, typename Map::key_type key)
{
	typename Map::const_iterator i = map.find(key);
	if (i != map.end())
	{
		return i->second;
	} else {
		return 0;
	}
}

/**
 * A basic FIR filter of variable type with float coeffs
 *
 * Note, coefficients will be normalized so that inputs
 * will always be scaled appropriately
 */
template<typename T>
class FIRFilter {
public:
	typedef std::vector<float> Coeffs;

	FIRFilter(const T& zero, size_t nrTaps) : _zero(zero) {
		if (nrTaps == 0)
			throw std::invalid_argument("FIR Filter: number of taps must be greater than zero");

		// initialize
		_taps.assign(nrTaps, _zero);
		_coeffs.assign(nrTaps, 0.0f);
		_coeffs[0] = 1.0;
	}

	T filter(const T& x) {
		_taps.push_front(x);
		_taps.pop_back();

		T y = _zero;
		for (size_t i = 0; i<_taps.size(); ++i)
			y += _taps.at(i) * _coeffs.at(i);

		return y;
	}

	/** reinitializes the coeffs and taps to new values */
	void setCoeffs(const Coeffs& coeffs) {
		size_t nrTaps = coeffs.size();
		if (nrTaps == 0)
			throw std::invalid_argument("FIR Filter: number of coeffs must be greater than zero");

		_taps.assign(nrTaps, _zero);
		_coeffs.assign(nrTaps, 0.0);

		// find the normalizer
		float normalizer = 0.0;
		for (size_t i = 0; i<coeffs.size(); ++i)
			normalizer += coeffs.at(i);

		// set the normalized coefficients
		for (size_t i=0; i<coeffs.size(); ++i)
			_coeffs[i] = coeffs.at(i) / normalizer;
	}

protected:
	T _zero;
	std::deque<T> _taps;
	Coeffs _coeffs;
};

// An output iterator which throws an exception when it's used.
// This is used for example to determine if the output of set_difference would be non-empty without
// calculating all of it.
template<typename T>
class ExceptionIterator: public std::iterator<std::output_iterator_tag, void, void, void, void>
{
public:
	ExceptionIterator &operator=(const T &value)
	{
		throw std::exception();
	}

	ExceptionIterator &operator*()
	{
		return *this;
	}

	ExceptionIterator &operator++()
	{
		return *this;
	}

	ExceptionIterator &operator++(int)
	{
		return *this;
	}
};

// Sets str to the name of a class.
// Use it like this:
//		Object *obj = new Object();
//		QString name = typeName(typeid(*obj));
// The returned name is in the usual C++ format: "Namespace::Namespace::Class"
QString typeName(const std::type_info &info);

// Like typeName, but only returns the final class name part.
QString className(const std::type_info &info);

/// Returns the absolute path to the 'run' directory
QDir ApplicationRunDirectory();
<commit_msg>Get rid of static in function declaration<commit_after>#pragma once

#include "Constants.hpp"
#include "Geometry2d/Point.hpp"
#include "time.hpp"

#include <cmath>
#include <deque>
#include <QString>
#include <stdexcept>
#include <stdint.h>
#include <sys/time.h>
#include <typeinfo>
#include <vector>
#include <QtWidgets>

const static bool THROW_DEBUG_EXCEPTIONS = true;

template <class exception>
inline void debugThrow(const exception &e) {
	if (THROW_DEBUG_EXCEPTIONS) {
		throw e;
	}
}

inline void debugThrow(const std::string &string) {
	if (THROW_DEBUG_EXCEPTIONS) {
		debugThrow(std::runtime_error(string));
	}
}

/**
 * @brief Restricts the given angle to be between pi and -pi
 *
 * @param a An angle in radians
 * @return An equivalent angle in radians restricted to [-pi, pi]
 */
static inline float fixAngleRadians(float a)
{
	a = remainder(a, 2*M_PI);
	while (a < -M_PI) a += 2.0*M_PI;
	while (a > M_PI) a -= 2.0*M_PI;
	return a;
}

/** Checks whether or not the given ball is in the defense area. */
static inline bool ballIsInGoalieBox(Geometry2d::Point point) {
	if (std::abs(point.x) < Field_Dimensions::Current_Dimensions.GoalFlat() / 2.0f) // Ball is in center (rectangular) portion of defensive bubble
	{
		return point.y > 0 && point.y < Field_Dimensions::Current_Dimensions.ArcRadius();
	} else if (std::abs(point.x) < (Field_Dimensions::Current_Dimensions.ArcRadius() + Field_Dimensions::Current_Dimensions.GoalFlat() / 2.0f)) // Ball is in one of the side (arc) portions of defensive bubble
	{
		double adjusted_x = std::abs(point.x) - (Field_Dimensions::Current_Dimensions.GoalFlat() / 2.0f);
		double max_y = sqrt( (Field_Dimensions::Current_Dimensions.ArcRadius() * Field_Dimensions::Current_Dimensions.ArcRadius()) - (adjusted_x * adjusted_x));
		return point.y > 0 && point.y <= max_y;
	}
	return false;
}

static Geometry2d::Point fromOursToTheirs(Geometry2d::Point &pt) {
	Geometry2d::Point c;
	c.y = Field_Dimensions::Current_Dimensions.Length() - pt.y;
	c.x = -pt.x;

	return c;
}

static bool ballIsInTheirGoalieBox(Geometry2d::Point &pt) {
	Geometry2d::Point converted = fromOursToTheirs(pt);
	return ballIsInGoalieBox(converted);
}

/** Returns @value if it is in bounds, otherwise returns the bound it is closest to */
template<class T>
float clamp(T value, T min, T max)
{
	if (value > max)
	{
		return max;
	}
	else if (value < min)
	{
		return min;
	}
	return value;
}

// Removes all entries in a std::map which associate to the given value.
template<class Map_Type, class Data_Type>
void map_remove(Map_Type &map, Data_Type &value)
{
	typename Map_Type::iterator i = map.begin();
	while (i != map.end())
	{
		typename Map_Type::iterator next = i;
		++next;

		if (i->second == value)
		{
			map.erase(i);
		}

		i = next;
	}
}

// If <key> exists in <map>, returns map[key].
// If not, returns 0.
template<typename Map>
typename Map::mapped_type map_lookup(const Map &map, typename Map::key_type key)
{
	typename Map::const_iterator i = map.find(key);
	if (i != map.end())
	{
		return i->second;
	} else {
		return 0;
	}
}

/**
 * A basic FIR filter of variable type with float coeffs
 *
 * Note, coefficients will be normalized so that inputs
 * will always be scaled appropriately
 */
template<typename T>
class FIRFilter {
public:
	typedef std::vector<float> Coeffs;

	FIRFilter(const T& zero, size_t nrTaps) : _zero(zero) {
		if (nrTaps == 0)
			throw std::invalid_argument("FIR Filter: number of taps must be greater than zero");

		// initialize
		_taps.assign(nrTaps, _zero);
		_coeffs.assign(nrTaps, 0.0f);
		_coeffs[0] = 1.0;
	}

	T filter(const T& x) {
		_taps.push_front(x);
		_taps.pop_back();

		T y = _zero;
		for (size_t i = 0; i<_taps.size(); ++i)
			y += _taps.at(i) * _coeffs.at(i);

		return y;
	}

	/** reinitializes the coeffs and taps to new values */
	void setCoeffs(const Coeffs& coeffs) {
		size_t nrTaps = coeffs.size();
		if (nrTaps == 0)
			throw std::invalid_argument("FIR Filter: number of coeffs must be greater than zero");

		_taps.assign(nrTaps, _zero);
		_coeffs.assign(nrTaps, 0.0);

		// find the normalizer
		float normalizer = 0.0;
		for (size_t i = 0; i<coeffs.size(); ++i)
			normalizer += coeffs.at(i);

		// set the normalized coefficients
		for (size_t i=0; i<coeffs.size(); ++i)
			_coeffs[i] = coeffs.at(i) / normalizer;
	}

protected:
	T _zero;
	std::deque<T> _taps;
	Coeffs _coeffs;
};

// An output iterator which throws an exception when it's used.
// This is used for example to determine if the output of set_difference would be non-empty without
// calculating all of it.
template<typename T>
class ExceptionIterator: public std::iterator<std::output_iterator_tag, void, void, void, void>
{
public:
	ExceptionIterator &operator=(const T &value)
	{
		throw std::exception();
	}

	ExceptionIterator &operator*()
	{
		return *this;
	}

	ExceptionIterator &operator++()
	{
		return *this;
	}

	ExceptionIterator &operator++(int)
	{
		return *this;
	}
};

// Sets str to the name of a class.
// Use it like this:
//		Object *obj = new Object();
//		QString name = typeName(typeid(*obj));
// The returned name is in the usual C++ format: "Namespace::Namespace::Class"
QString typeName(const std::type_info &info);

// Like typeName, but only returns the final class name part.
QString className(const std::type_info &info);

/// Returns the absolute path to the 'run' directory
QDir ApplicationRunDirectory();
<|endoftext|>


<commit_before>// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/nss_init.h"

#include <nss.h>
#include <plarena.h>
#include <prerror.h>
#include <prinit.h>

// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
// until NSS 3.12.2 comes out and we update to it.
#define Lock FOO_NSS_Lock
#include <pk11pub.h>
#include <secmod.h>
#include <ssl.h>
#undef Lock

#include "base/file_util.h"
#include "base/logging.h"
#include "base/singleton.h"
#include "base/string_util.h"

namespace {

std::string GetDefaultConfigDirectory() {
  const char* home = getenv("HOME");
  if (home == NULL) {
    LOG(ERROR) << "$HOME is not set.";
    return "";
  }
  FilePath dir(home);
  dir = dir.AppendASCII(".pki").AppendASCII("nssdb");
  if (!file_util::CreateDirectory(dir)) {
    LOG(ERROR) << "Failed to create ~/.pki/nssdb directory.";
    return "";
  }
  return dir.value();
}

// Load nss's built-in root certs.
SECMODModule *InitDefaultRootCerts() {
  const char* kModulePath = "libnssckbi.so";
  char modparams[1024];
  snprintf(modparams, sizeof(modparams),
          "name=\"Root Certs\" library=\"%s\"", kModulePath);
  SECMODModule *root = SECMOD_LoadUserModule(modparams, NULL, PR_FALSE);
  if (root)
    return root;

  // Aw, snap.  Can't find/load root cert shared library.
  // This will make it hard to talk to anybody via https.
  NOTREACHED();
  return NULL;
}

class NSSInitSingleton {
 public:
  NSSInitSingleton() {
    SECStatus status;
    std::string database_dir = GetDefaultConfigDirectory();
    if (!database_dir.empty()) {
      // Initialize with a persistant database (~/.pki/nssdb).
      // Use "sql:" which can be shared by multiple processes safely.
      status = NSS_InitReadWrite(
          StringPrintf("sql:%s", database_dir.c_str()).c_str());
    } else {
      LOG(WARNING) << "Initialize NSS without using a persistent database "
                   << "(~/.pki/nssdb).";
      status = NSS_NoDB_Init(".");
    }
    if (status != SECSuccess) {
      char buffer[513] = "Couldn't retrieve error";
      PRInt32 err_length = PR_GetErrorTextLength();
      if (err_length > 0 && static_cast<size_t>(err_length) < sizeof(buffer))
        PR_GetErrorText(buffer);

      NOTREACHED() << "Error initializing NSS: " << buffer;
    }

    // If we haven't initialized the password for the NSS databases,
    // initialize an empty-string password so that we don't need to
    // log in.
    PK11SlotInfo* slot = PK11_GetInternalKeySlot();
    if (slot) {
      if (PK11_NeedUserInit(slot))
        PK11_InitPin(slot, NULL, NULL);
      PK11_FreeSlot(slot);
    }

    root_ = InitDefaultRootCerts();

    NSS_SetDomesticPolicy();

    // Explicitly enable exactly those ciphers with keys of at least 80 bits
    for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
      SSLCipherSuiteInfo info;
      if (SSL_GetCipherSuiteInfo(SSL_ImplementedCiphers[i], &info,
                                 sizeof(info)) == SECSuccess) {
        SSL_CipherPrefSetDefault(SSL_ImplementedCiphers[i],
                                 (info.effectiveKeyBits >= 80));
      }
    }

    // Enable SSL
    SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);

    // All other SSL options are set per-session by SSLClientSocket.
  }

  ~NSSInitSingleton() {
    if (root_) {
      SECMOD_UnloadUserModule(root_);
      SECMOD_DestroyModule(root_);
      root_ = NULL;
    }

    // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY
    SSL_ClearSessionCache();

    SECStatus status = NSS_Shutdown();
    if (status != SECSuccess)
      LOG(ERROR) << "NSS_Shutdown failed, leak?  See "
                    "http://code.google.com/p/chromium/issues/detail?id=4609";

    PL_ArenaFinish();

    PRStatus prstatus = PR_Cleanup();
    if (prstatus != PR_SUCCESS)
      LOG(ERROR) << "PR_Cleanup failed?";
  }

 private:
  SECMODModule *root_;
};

}  // namespace

namespace base {

void EnsureNSSInit() {
  Singleton<NSSInitSingleton>::get();
}

}  // namespace base
<commit_msg>Avoid runtime linker warning  "Symbol `SSL_ImplementedCiphers' has different size in shared object, consider re-linking" if SSL_ImplementedCiphers is different size on target system than it was on build system.<commit_after>// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/nss_init.h"

#include <dlfcn.h>
#include <nss.h>
#include <plarena.h>
#include <prerror.h>
#include <prinit.h>

// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
// until NSS 3.12.2 comes out and we update to it.
#define Lock FOO_NSS_Lock
#include <pk11pub.h>
#include <secmod.h>
#include <ssl.h>
#undef Lock

#include "base/file_util.h"
#include "base/logging.h"
#include "base/singleton.h"
#include "base/string_util.h"

namespace {

std::string GetDefaultConfigDirectory() {
  const char* home = getenv("HOME");
  if (home == NULL) {
    LOG(ERROR) << "$HOME is not set.";
    return "";
  }
  FilePath dir(home);
  dir = dir.AppendASCII(".pki").AppendASCII("nssdb");
  if (!file_util::CreateDirectory(dir)) {
    LOG(ERROR) << "Failed to create ~/.pki/nssdb directory.";
    return "";
  }
  return dir.value();
}

// Load nss's built-in root certs.
SECMODModule *InitDefaultRootCerts() {
  const char* kModulePath = "libnssckbi.so";
  char modparams[1024];
  snprintf(modparams, sizeof(modparams),
          "name=\"Root Certs\" library=\"%s\"", kModulePath);
  SECMODModule *root = SECMOD_LoadUserModule(modparams, NULL, PR_FALSE);
  if (root)
    return root;

  // Aw, snap.  Can't find/load root cert shared library.
  // This will make it hard to talk to anybody via https.
  NOTREACHED();
  return NULL;
}

class NSSInitSingleton {
 public:
  NSSInitSingleton() {
    SECStatus status;
    std::string database_dir = GetDefaultConfigDirectory();
    if (!database_dir.empty()) {
      // Initialize with a persistant database (~/.pki/nssdb).
      // Use "sql:" which can be shared by multiple processes safely.
      status = NSS_InitReadWrite(
          StringPrintf("sql:%s", database_dir.c_str()).c_str());
    } else {
      LOG(WARNING) << "Initialize NSS without using a persistent database "
                   << "(~/.pki/nssdb).";
      status = NSS_NoDB_Init(".");
    }
    if (status != SECSuccess) {
      char buffer[513] = "Couldn't retrieve error";
      PRInt32 err_length = PR_GetErrorTextLength();
      if (err_length > 0 && static_cast<size_t>(err_length) < sizeof(buffer))
        PR_GetErrorText(buffer);

      NOTREACHED() << "Error initializing NSS: " << buffer;
    }

    // If we haven't initialized the password for the NSS databases,
    // initialize an empty-string password so that we don't need to
    // log in.
    PK11SlotInfo* slot = PK11_GetInternalKeySlot();
    if (slot) {
      if (PK11_NeedUserInit(slot))
        PK11_InitPin(slot, NULL, NULL);
      PK11_FreeSlot(slot);
    }

    root_ = InitDefaultRootCerts();

    NSS_SetDomesticPolicy();

    // Use late binding to avoid scary but benign warning
    // "Symbol `SSL_ImplementedCiphers' has different size in shared object,
    //  consider re-linking"
    const PRUint16* pSSL_ImplementedCiphers = static_cast<const PRUint16*>(
        dlsym(RTLD_DEFAULT, "SSL_ImplementedCiphers"));
    if (pSSL_ImplementedCiphers == NULL) {
      NOTREACHED() << "Can't get list of supported ciphers";
      return;
    }

    // Explicitly enable exactly those ciphers with keys of at least 80 bits
    for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
      SSLCipherSuiteInfo info;
      if (SSL_GetCipherSuiteInfo(pSSL_ImplementedCiphers[i], &info,
                                 sizeof(info)) == SECSuccess) {
        SSL_CipherPrefSetDefault(pSSL_ImplementedCiphers[i],
                                 (info.effectiveKeyBits >= 80));
      }
    }

    // Enable SSL
    SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);

    // All other SSL options are set per-session by SSLClientSocket.
  }

  ~NSSInitSingleton() {
    if (root_) {
      SECMOD_UnloadUserModule(root_);
      SECMOD_DestroyModule(root_);
      root_ = NULL;
    }

    // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY
    SSL_ClearSessionCache();

    SECStatus status = NSS_Shutdown();
    if (status != SECSuccess)
      LOG(ERROR) << "NSS_Shutdown failed, leak?  See "
                    "http://code.google.com/p/chromium/issues/detail?id=4609";

    PL_ArenaFinish();

    PRStatus prstatus = PR_Cleanup();
    if (prstatus != PR_SUCCESS)
      LOG(ERROR) << "PR_Cleanup failed?";
  }

 private:
  SECMODModule *root_;
};

}  // namespace

namespace base {

void EnsureNSSInit() {
  Singleton<NSSInitSingleton>::get();
}

}  // namespace base
<|endoftext|>


<commit_before>#ifndef AMGCL_MAKE_BLOCK_SOLVER_HPP
#define AMGCL_MAKE_BLOCK_SOLVER_HPP

#include <amgcl/backend/interface.hpp>
#include <amgcl/adapter/block_matrix.hpp>
#include <amgcl/value_type/static_matrix.hpp>
#include <amgcl/make_solver.hpp>
#include <amgcl/util.hpp>

namespace amgcl {

namespace backend {

} // namespace backend

/* Creates solver that operates in non-scalar domain but may take scalar inputs
 * for the system matrix and the rhs/solution vectors.
 */
template <class Precond, class IterativeSolver>
class make_block_solver {
    public:
        typedef typename Precond::backend_type             backend_type;
        typedef typename backend_type::value_type          value_type;
        typedef typename backend_type::params              backend_params;
        typedef typename backend_type::vector              vector;
        typedef typename math::scalar_of<value_type>::type scalar_type;
        typedef typename math::rhs_of<value_type>::type    rhs_type;

        typedef typename make_solver<Precond, IterativeSolver>::params params;

        template <class Matrix>
        make_block_solver(
                const Matrix &A,
                const params &prm = params(),
                const backend_params &bprm = backend_params()
                )
        {
            S = std::make_shared<Solver>(adapter::block_matrix<value_type>(A), prm, bprm);
        }

        template <class Matrix, class Vec1, class Vec2>
        std::tuple<size_t, scalar_type> operator()(
                const Matrix &A, const Vec1 &rhs, Vec2 &&x) const
        {
            const size_t n = backend::rows(system_matrix());

            rhs_type const * fptr = reinterpret_cast<rhs_type const *>(&rhs[0]);
            rhs_type       * xptr = reinterpret_cast<rhs_type       *>(&x[0]);

            iterator_range<rhs_type const *> frng(fptr, fptr + n);
            iterator_range<rhs_type       *> xrng(xptr, xptr + n);

            return (*S)(A, frng, xrng);
        }

        template <class Vec1, class Vec2>
        std::tuple<size_t, scalar_type>
        operator()(const Vec1 &rhs, Vec2 &&x) const {
            const size_t n = backend::rows(system_matrix());

            rhs_type const * fptr = reinterpret_cast<rhs_type const *>(&rhs[0]);
            rhs_type       * xptr = reinterpret_cast<rhs_type       *>(&x[0]);

            iterator_range<rhs_type const *> frng(fptr, fptr + n);
            iterator_range<rhs_type       *> xrng(xptr, xptr + n);

            return (*S)(frng, xrng);
        }

        std::shared_ptr<typename Precond::matrix> system_matrix_ptr() const {
            return S->system_matrix_ptr();
        }

        typename Precond::matrix const& system_matrix() const {
            return S->system_matrix();
        }

        friend std::ostream& operator<<(std::ostream &os, const make_block_solver &p) {
            return os << *p.S << std::endl;
        }

        size_t bytes() const {
            return backend::bytes(*S);
        }
    private:
        typedef make_solver<Precond, IterativeSolver> Solver;
        std::shared_ptr<Solver> S;
};

} // namespace amgcl

#endif
<commit_msg>Support mixed precision in block solver<commit_after>#ifndef AMGCL_MAKE_BLOCK_SOLVER_HPP
#define AMGCL_MAKE_BLOCK_SOLVER_HPP

#include <amgcl/backend/interface.hpp>
#include <amgcl/adapter/block_matrix.hpp>
#include <amgcl/value_type/static_matrix.hpp>
#include <amgcl/make_solver.hpp>
#include <amgcl/util.hpp>

namespace amgcl {

namespace backend {

} // namespace backend

/* Creates solver that operates in non-scalar domain but may take scalar inputs
 * for the system matrix and the rhs/solution vectors.
 */
template <class Precond, class IterativeSolver>
class make_block_solver {
    public:
        typedef typename Precond::backend_type             backend_type;
        typedef typename backend_type::value_type          value_type;
        typedef typename backend_type::params              backend_params;
        typedef typename backend_type::vector              vector;
        typedef typename math::scalar_of<value_type>::type scalar_type;
        typedef typename math::rhs_of<value_type>::type    rhs_type;

        typedef typename make_solver<Precond, IterativeSolver>::params params;

        template <class Matrix>
        make_block_solver(
                const Matrix &A,
                const params &prm = params(),
                const backend_params &bprm = backend_params()
                )
        {
            S = std::make_shared<Solver>(adapter::block_matrix<value_type>(A), prm, bprm);
        }

        template <class Matrix, class Vec1, class Vec2>
        std::tuple<size_t, scalar_type> operator()(
                const Matrix &A, const Vec1 &rhs, Vec2 &&x) const
        {
            const size_t n = backend::rows(system_matrix());

            typedef typename math::scalar_of<typename backend::value_type<typename std::decay<Vec1>::type>::type>::type fs;
            typedef typename math::scalar_of<typename backend::value_type<typename std::decay<Vec2>::type>::type>::type xs;

            typedef typename math::replace_scalar<rhs_type, fs>::type f_type;
            typedef typename math::replace_scalar<rhs_type, xs>::type x_type;

            f_type const * fptr = reinterpret_cast<f_type const *>(&rhs[0]);
            x_type       * xptr = reinterpret_cast<x_type       *>(&x[0]);

            iterator_range<f_type const *> frng(fptr, fptr + n);
            iterator_range<x_type       *> xrng(xptr, xptr + n);

            return (*S)(A, frng, xrng);
        }

        template <class Vec1, class Vec2>
        std::tuple<size_t, scalar_type>
        operator()(const Vec1 &rhs, Vec2 &&x) const {
            const size_t n = backend::rows(system_matrix());

            typedef typename math::scalar_of<typename backend::value_type<typename std::decay<Vec1>::type>::type>::type fs;
            typedef typename math::scalar_of<typename backend::value_type<typename std::decay<Vec2>::type>::type>::type xs;

            typedef typename math::replace_scalar<rhs_type, fs>::type f_type;
            typedef typename math::replace_scalar<rhs_type, xs>::type x_type;

            f_type const * fptr = reinterpret_cast<f_type const *>(&rhs[0]);
            x_type       * xptr = reinterpret_cast<x_type       *>(&x[0]);

            iterator_range<f_type const *> frng(fptr, fptr + n);
            iterator_range<x_type       *> xrng(xptr, xptr + n);

            return (*S)(frng, xrng);
        }

        std::shared_ptr<typename Precond::matrix> system_matrix_ptr() const {
            return S->system_matrix_ptr();
        }

        typename Precond::matrix const& system_matrix() const {
            return S->system_matrix();
        }

        friend std::ostream& operator<<(std::ostream &os, const make_block_solver &p) {
            return os << *p.S << std::endl;
        }

        size_t bytes() const {
            return backend::bytes(*S);
        }
    private:
        typedef make_solver<Precond, IterativeSolver> Solver;
        std::shared_ptr<Solver> S;
};

} // namespace amgcl

#endif
<|endoftext|>


<commit_before>#include <tests/Base.hh>

#include <aleph/persistentHomology/algorithms/Standard.hh>
#include <aleph/persistentHomology/PhiPersistence.hh>

#include <aleph/topology/Conversions.hh>
#include <aleph/topology/QuotientSpaces.hh>
#include <aleph/topology/Simplex.hh>
#include <aleph/topology/SimplicialComplex.hh>

#include <unordered_map>
#include <vector>

template <class T> void test()
{
  ALEPH_TEST_BEGIN( "Persistent intersection homology: simple example" );

  using Simplex           = aleph::topology::Simplex<T>;
  using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

  std::vector<Simplex> simplices =
  {
    {0},
    {1},
    {2},
    {3},
    {4},
    {0,1}, {0,3}, {0,4},
    {1,2}, {1,4},
    {2,3}, {2,4},
    {3,4},
    {0,3,4}, // A
    {1,2,4}, // B
    {2,3,4}, // C
    {0,1,4}  // E
  };

  std::map<Simplex, bool> phi;

  for( auto&& simplex : simplices )
  {
    if( simplex.contains(4) == false || simplex.dimension() == 2 )
      phi[simplex] = true;
    else
      phi[simplex] = false;
  }

  SimplicialComplex K( simplices.begin(), simplices.end() );
  SimplicialComplex L;

  std::size_t s    = 0;
  std::tie( L, s ) =
    aleph::partition( K,
                      [&phi] ( const Simplex& s )
                      {
                        return phi.at(s);
                      } );

  ALEPH_ASSERT_EQUAL( K.size(), L.size() );

  auto boundaryMatrix = aleph::topology::makeBoundaryMatrix( L, s );
  auto indexA         = L.index( {0,3,4} );

  using IndexType     = typename decltype(boundaryMatrix)::Index;
  auto columnA        = boundaryMatrix.getColumn( static_cast<IndexType>( indexA ) );

  ALEPH_ASSERT_EQUAL( columnA.size(), 3 );

  aleph::persistentHomology::algorithms::Standard algorithm;
  algorithm( boundaryMatrix );

  unsigned numAllowableChains    = 0;
  unsigned numAllowableTwoChains = 0;

  for( IndexType i = 0; i < boundaryMatrix.getNumColumns(); i++ )
  {
    auto lowestOne = boundaryMatrix.getMaximumIndex( i );
    if( lowestOne.second && lowestOne.first <= s )
    {
      ++numAllowableChains;

      if( L.at(i).dimension() == 2 )
        ++numAllowableTwoChains;
    }
  }

  ALEPH_ASSERT_THROW( numAllowableChains >= numAllowableTwoChains );
  ALEPH_ASSERT_EQUAL( numAllowableTwoChains, 1 );

  ALEPH_TEST_END();
}

template <class T> void testQuotientSpaces()
{
  ALEPH_TEST_BEGIN( "Persistent intersection homology: quotient spaces" );

  using Simplex           = aleph::topology::Simplex<T>;
  using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

  SimplicialComplex K = {
    {0},
    {1},
    {2},
    {3},
    {0,1}, {0,2}, {0,3},
    {1,2}, {1,3},
    {2,3},
    {0,1,2}, {0,1,3}, {0,2,3},
    {1,2,3},
    {0,1,2,3}
  };

  auto C = aleph::topology::cone( K );
  auto S = aleph::topology::suspension( K );

  ALEPH_ASSERT_THROW( C.empty() == false );
  ALEPH_ASSERT_THROW( S.empty() == false );
  ALEPH_ASSERT_EQUAL( C.size(), 2 * K.size() + 1);
  ALEPH_ASSERT_EQUAL( S.size(), 3 * K.size() + 2);

  ALEPH_TEST_END();
}

template <class T> void testWedgeOfTwoCircles()
{
  ALEPH_TEST_BEGIN( "Persistent intersection homology: wedge of two circles" );

  using Simplex           = aleph::topology::Simplex<T>;
  using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

  SimplicialComplex K = {
    {0},
    {1},
    {2},
    {3},
    {4},
    {5},
    {6},
    {0,1}, {0,6},
    {1,2},
    {2,3}, {2,5}, {2,6},
    {3,4},
    {4,5}
  };

  SimplicialComplex X0 = { {2} };
  SimplicialComplex X1 = K;

  auto D1 = aleph::calculateIntersectionHomology( K, {X0,X1}, aleph::Perversity( {-1,-1} ) );
  auto D2 = aleph::calculateIntersectionHomology( K, {X0,X1}, aleph::Perversity( { 0, 0} ) );

  ALEPH_ASSERT_EQUAL( D1.size(), 1 );
  ALEPH_ASSERT_EQUAL( D2.size(), 2 );

  ALEPH_ASSERT_EQUAL( D1[0].betti(), 2 );

  // TODO: is this correct? In his Ph.D. thesis "Analyzing Stratified
  // Spaces Using Persistent Versions of Intersection and Local
  // Homology", Bendich states that this should be 0...
  ALEPH_ASSERT_EQUAL( D2[0].betti(), 1 );
  ALEPH_ASSERT_EQUAL( D2[1].betti(), 2 );

  ALEPH_TEST_END();
}

int main(int, char**)
{
  test<float> ();
  test<double>();

  testQuotientSpaces<float> ();
  testQuotientSpaces<double>();

  testWedgeOfTwoCircles<float> ();
  testWedgeOfTwoCircles<double>();
}
<commit_msg>Extended test case for quotient spaces with homology calculations<commit_after>#include <tests/Base.hh>

#include <aleph/persistentHomology/algorithms/Standard.hh>

#include <aleph/persistentHomology/Calculation.hh>
#include <aleph/persistentHomology/PhiPersistence.hh>

#include <aleph/topology/Conversions.hh>
#include <aleph/topology/QuotientSpaces.hh>
#include <aleph/topology/Simplex.hh>
#include <aleph/topology/SimplicialComplex.hh>

#include <unordered_map>
#include <vector>

template <class T> void test()
{
  ALEPH_TEST_BEGIN( "Persistent intersection homology: simple example" );

  using Simplex           = aleph::topology::Simplex<T>;
  using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

  std::vector<Simplex> simplices =
  {
    {0},
    {1},
    {2},
    {3},
    {4},
    {0,1}, {0,3}, {0,4},
    {1,2}, {1,4},
    {2,3}, {2,4},
    {3,4},
    {0,3,4}, // A
    {1,2,4}, // B
    {2,3,4}, // C
    {0,1,4}  // E
  };

  std::map<Simplex, bool> phi;

  for( auto&& simplex : simplices )
  {
    if( simplex.contains(4) == false || simplex.dimension() == 2 )
      phi[simplex] = true;
    else
      phi[simplex] = false;
  }

  SimplicialComplex K( simplices.begin(), simplices.end() );
  SimplicialComplex L;

  std::size_t s    = 0;
  std::tie( L, s ) =
    aleph::partition( K,
                      [&phi] ( const Simplex& s )
                      {
                        return phi.at(s);
                      } );

  ALEPH_ASSERT_EQUAL( K.size(), L.size() );

  auto boundaryMatrix = aleph::topology::makeBoundaryMatrix( L, s );
  auto indexA         = L.index( {0,3,4} );

  using IndexType     = typename decltype(boundaryMatrix)::Index;
  auto columnA        = boundaryMatrix.getColumn( static_cast<IndexType>( indexA ) );

  ALEPH_ASSERT_EQUAL( columnA.size(), 3 );

  aleph::persistentHomology::algorithms::Standard algorithm;
  algorithm( boundaryMatrix );

  unsigned numAllowableChains    = 0;
  unsigned numAllowableTwoChains = 0;

  for( IndexType i = 0; i < boundaryMatrix.getNumColumns(); i++ )
  {
    auto lowestOne = boundaryMatrix.getMaximumIndex( i );
    if( lowestOne.second && lowestOne.first <= s )
    {
      ++numAllowableChains;

      if( L.at(i).dimension() == 2 )
        ++numAllowableTwoChains;
    }
  }

  ALEPH_ASSERT_THROW( numAllowableChains >= numAllowableTwoChains );
  ALEPH_ASSERT_EQUAL( numAllowableTwoChains, 1 );

  ALEPH_TEST_END();
}

template <class T> void testQuotientSpaces()
{
  ALEPH_TEST_BEGIN( "Persistent intersection homology: quotient spaces" );

  using Simplex           = aleph::topology::Simplex<T>;
  using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

  SimplicialComplex K = {
    {0},
    {1},
    {2},
    {3},
    {0,1}, {0,2}, {0,3},
    {1,2}, {1,3},
    {2,3},
    {0,1,2}, {0,1,3}, {0,2,3},
    {1,2,3}
  };

  auto C = aleph::topology::cone( K );
  auto S = aleph::topology::suspension( K );

  ALEPH_ASSERT_THROW( C.empty() == false );
  ALEPH_ASSERT_THROW( S.empty() == false );
  ALEPH_ASSERT_EQUAL( C.size(), 2 * K.size() + 1);
  ALEPH_ASSERT_EQUAL( S.size(), 3 * K.size() + 2);

  S.sort();

  bool dualize                    = true;
  bool includeAllUnpairedCreators = true;

  auto D1 = aleph::calculatePersistenceDiagrams(K, dualize, includeAllUnpairedCreators);
  auto D2 = aleph::calculatePersistenceDiagrams(S, dualize, includeAllUnpairedCreators);

  ALEPH_ASSERT_EQUAL( D1.size(), 3 );
  ALEPH_ASSERT_EQUAL( D2.size(), 4 );

  std::vector<std::size_t> expectedBettiNumbersK = {1,0,1};
  std::vector<std::size_t> expectedBettiNumbersS = {1,0,0,1};

  std::vector<std::size_t> bettiNumbersK;
  std::vector<std::size_t> bettiNumbersS;

  using PersistenceDiagram = decltype( D1.front() );

  std::transform( D1.begin(), D1.end(), std::back_inserter( bettiNumbersK ), [] ( const PersistenceDiagram& D ) { return D.betti(); } );
  std::transform( D2.begin(), D2.end(), std::back_inserter( bettiNumbersS ), [] ( const PersistenceDiagram& D ) { return D.betti(); } );

  ALEPH_ASSERT_THROW( bettiNumbersK == expectedBettiNumbersK );
  ALEPH_ASSERT_THROW( bettiNumbersS == expectedBettiNumbersS );

  ALEPH_TEST_END();
}

template <class T> void testWedgeOfTwoCircles()
{
  ALEPH_TEST_BEGIN( "Persistent intersection homology: wedge of two circles" );

  using Simplex           = aleph::topology::Simplex<T>;
  using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

  SimplicialComplex K = {
    {0},
    {1},
    {2},
    {3},
    {4},
    {5},
    {6},
    {0,1}, {0,6},
    {1,2},
    {2,3}, {2,5}, {2,6},
    {3,4},
    {4,5}
  };

  SimplicialComplex X0 = { {2} };
  SimplicialComplex X1 = K;

  auto D1 = aleph::calculateIntersectionHomology( K, {X0,X1}, aleph::Perversity( {-1,-1} ) );
  auto D2 = aleph::calculateIntersectionHomology( K, {X0,X1}, aleph::Perversity( { 0, 0} ) );

  ALEPH_ASSERT_EQUAL( D1.size(), 1 );
  ALEPH_ASSERT_EQUAL( D2.size(), 2 );

  ALEPH_ASSERT_EQUAL( D1[0].betti(), 2 );

  // TODO: is this correct? In his Ph.D. thesis "Analyzing Stratified
  // Spaces Using Persistent Versions of Intersection and Local
  // Homology", Bendich states that this should be 0...
  ALEPH_ASSERT_EQUAL( D2[0].betti(), 1 );
  ALEPH_ASSERT_EQUAL( D2[1].betti(), 2 );

  ALEPH_TEST_END();
}

int main(int, char**)
{
  test<float> ();
  test<double>();

  testQuotientSpaces<float> ();
  testQuotientSpaces<double>();

  testWedgeOfTwoCircles<float> ();
  testWedgeOfTwoCircles<double>();
}
<|endoftext|>


<commit_before>#include <cthun-agent/modules/status.hpp>
#include <cthun-agent/file_utils.hpp>
#include <cthun-agent/configuration.hpp>
#include <cthun-agent/errors.hpp>

#include <fstream>

#define LEATHERMAN_LOGGING_NAMESPACE "puppetlabs.cthun_agent.modules.status"
#include <leatherman/logging/logging.hpp>

namespace CthunAgent {
namespace Modules {

static const std::string QUERY { "query" };

Status::Status() {
    module_name = "status";
    actions.push_back(QUERY);
    CthunClient::Schema input_schema { QUERY };
    CthunClient::Schema output_schema { QUERY };

    input_validator_.registerSchema(input_schema);
    output_validator_.registerSchema(output_schema);
}

ActionOutcome Status::callAction(const std::string& action_name,
                                 const CthunClient::ParsedChunks& parsed_chunks) {
    CthunClient::DataContainer results {};
    auto request_input = parsed_chunks.data
                                      .get<CthunClient::DataContainer>("params");
    auto job_id = request_input.get<std::string>("job_id");
    auto spool_dir = Configuration::Instance().get<std::string>("spool-dir");

    if (!FileUtils::fileExists(spool_dir + job_id)) {
        LOG_ERROR("Found no results for job id %1%", job_id);
        results.set<std::string>("error", "No job exists for id: " + job_id);
        return results;
    }

    CthunClient::DataContainer status {
        FileUtils::readFileAsString(spool_dir + job_id + "/status") };

    auto status_txt = status.get<std::string>("status");
    if (status_txt == "running") {
        results.set<std::string>("status", "Running");
    } else if (status_txt == "completed") {
        results.set<std::string>("status", "Completed");
        results.set<std::string>("stdout",
                    FileUtils::readFileAsString(spool_dir + job_id + "/stdout"));
        results.set<std::string>("stderr",
                    FileUtils::readFileAsString(spool_dir + job_id + "/stderr"));
    } else {
        std::string tmp { "Job '" + job_id + "' is in unknown state: " };
        results.set<std::string>("status", tmp + status_txt);
    }

    return ActionOutcome { results };
}

}  // namespace Modules
}  // namespace CthunAgent
<commit_msg>(maint) Add TODO message for status action response<commit_after>#include <cthun-agent/modules/status.hpp>
#include <cthun-agent/file_utils.hpp>
#include <cthun-agent/configuration.hpp>
#include <cthun-agent/errors.hpp>

#include <fstream>

#define LEATHERMAN_LOGGING_NAMESPACE "puppetlabs.cthun_agent.modules.status"
#include <leatherman/logging/logging.hpp>

namespace CthunAgent {
namespace Modules {

static const std::string QUERY { "query" };

Status::Status() {
    module_name = "status";
    actions.push_back(QUERY);
    CthunClient::Schema input_schema { QUERY };
    CthunClient::Schema output_schema { QUERY };

    input_validator_.registerSchema(input_schema);
    output_validator_.registerSchema(output_schema);
}

ActionOutcome Status::callAction(const std::string& action_name,
                                 const CthunClient::ParsedChunks& parsed_chunks) {
    CthunClient::DataContainer results {};
    auto request_input = parsed_chunks.data
                                      .get<CthunClient::DataContainer>("params");
    auto job_id = request_input.get<std::string>("job_id");
    auto spool_dir = Configuration::Instance().get<std::string>("spool-dir");

    if (!FileUtils::fileExists(spool_dir + job_id)) {
        // TODO(ale): return "unknown" in this case; see RPC specs

        LOG_ERROR("Found no results for job id %1%", job_id);
        results.set<std::string>("error", "No job exists for id: " + job_id);
        return results;
    }

    CthunClient::DataContainer status {
        FileUtils::readFileAsString(spool_dir + job_id + "/status") };

    auto status_txt = status.get<std::string>("status");
    if (status_txt == "running") {
        results.set<std::string>("status", "Running");
    } else if (status_txt == "completed") {
        results.set<std::string>("status", "Completed");
        results.set<std::string>("stdout",
                    FileUtils::readFileAsString(spool_dir + job_id + "/stdout"));
        results.set<std::string>("stderr",
                    FileUtils::readFileAsString(spool_dir + job_id + "/stderr"));
    } else {
        std::string tmp { "Job '" + job_id + "' is in unknown state: " };
        results.set<std::string>("status", tmp + status_txt);
    }

    return ActionOutcome { results };
}

}  // namespace Modules
}  // namespace CthunAgent
<|endoftext|>