static inline void debug_turn(Turn const& t, bool non_crossing)
 {
     std::cout << "checking turn @"
               << geometry::wkt(t.point)
               << "; " << method_char(t.method)
               << ":" << operation_char(t.operations[0].operation)
               << "/" << operation_char(t.operations[1].operation)
               << "; non-crossing? "
               << std::boolalpha << non_crossing << std::noboolalpha
               << std::endl;
 }
 static inline void debug_follow(Turn const& turn, Operation op,
                                 int index)
 {
     std::cout << index
               << " at " << op.seg_id
               << " meth: " << method_char(turn.method)
               << " op: " << operation_char(op.operation)
               << " vis: " << visited_char(op.visited)
               << " of:  " << operation_char(turn.operations[0].operation)
               << operation_char(turn.operations[1].operation)
               << " " << geometry::wkt(turn.point)
               << std::endl;
 }
inline bool has_self_intersections(Geometry const& geometry)
{
    typedef typename point_type<Geometry>::type point_type;
    typedef detail::overlay::turn_info<point_type> turn_info;
    std::deque<turn_info> turns;
    detail::disjoint::disjoint_interrupt_policy policy;
    geometry::self_turns<detail::overlay::assign_null_policy>(geometry, turns, policy);
    
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
    bool first = true;
#endif    
    for(typename std::deque<turn_info>::const_iterator it = boost::begin(turns); 
        it != boost::end(turns); ++it)
    {
        turn_info const& info = *it;
        bool const both_union_turn = 
            info.operations[0].operation == detail::overlay::operation_union
            && info.operations[1].operation == detail::overlay::operation_union;
        bool const both_intersection_turn = 
            info.operations[0].operation == detail::overlay::operation_intersection
            && info.operations[1].operation == detail::overlay::operation_intersection;

        bool const valid = (both_union_turn || both_intersection_turn)
            && (info.method == detail::overlay::method_touch
                || info.method == detail::overlay::method_touch_interior);

        if (! valid)
        {
#ifdef BOOST_GEOMETRY_DEBUG_HAS_SELF_INTERSECTIONS
            if (first)
            {
                std::cout << "turn points: " << std::endl;
                first = false;
            }
            std::cout << method_char(info.method);
            for (int i = 0; i < 2; i++)
            {
                std::cout << " " << operation_char(info.operations[i].operation);
                std::cout << " " << info.operations[i].seg_id;
            }
            std::cout << " " << geometry::dsv(info.point) << std::endl;
#endif

#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
            throw overlay_invalid_input_exception();
#endif
        }

    }
    return false;
}
Beispiel #4
0
inline void display(MetaTurn const& meta_turn, std::string const& reason = "")
{
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
    std::cout << meta_turn.index
        << "\tMethods: " << method_char(meta_turn.turn->method)
        << " operations: "  << operation_char(meta_turn.turn->operations[0].operation)
                << operation_char(meta_turn.turn->operations[1].operation)
        << " travels to " << meta_turn.turn->operations[0].enriched.travels_to_ip_index
        << " and " << meta_turn.turn->operations[1].enriched.travels_to_ip_index
        //<< " -> " << op_index
        << " " << reason
        << std::endl;
#endif
}
Beispiel #5
0
inline void debug_turn(Turn const& turn, Operation op,
                       std::string const& header)
{
    std::cout << header
        << " at " << op.seg_id
        << " meth: " << method_char(turn.method)
        << " op: " << operation_char(op.operation)
        << " of: " << operation_char(turn.operations[0].operation)
        << operation_char(turn.operations[1].operation)
        << " " << geometry::wkt(turn.point)
        << std::endl;

    if (boost::contains(header, "Finished"))
    {
        std::cout << std::endl;
    }
}
inline void enrich_assign(Container& operations,
            TurnPoints& turn_points,
            operation_type for_operation,
            Geometry1 const& geometry1, Geometry2 const& geometry2,
            Strategy const& strategy)
{
    typedef typename IndexType::type operations_type;
    typedef typename boost::range_iterator<Container const>::type iterator_type;


    if (operations.size() > 0)
    {
        // Assign travel-to-vertex/ip index for each turning point.
        // Because IP's are circular, PREV starts at the very last one,
        // being assigned from the first one.
        // "next ip on same segment" should not be considered circular.
        bool first = true;
        iterator_type it = boost::begin(operations);
        for (iterator_type prev = it + (boost::size(operations) - 1);
             it != boost::end(operations);
             prev = it++)
        {
            operations_type& prev_op
                    = turn_points[prev->index].operations[prev->operation_index];
            operations_type& op
                    = turn_points[it->index].operations[it->operation_index];

            prev_op.enriched.travels_to_ip_index
                    = it->index;
            prev_op.enriched.travels_to_vertex_index
                    = it->subject.seg_id.segment_index;

            if (! first
                && prev_op.seg_id.segment_index == op.seg_id.segment_index)
            {
                prev_op.enriched.next_ip_index = it->index;
            }
            first = false;
        }
    }

    // DEBUG
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
    {
        for (iterator_type it = boost::begin(operations);
             it != boost::end(operations);
             ++it)
        {
            operations_type& op = turn_points[it->index]
                .operations[it->operation_index];

            std::cout << it->index
                << " meth: " << method_char(turn_points[it->index].method)
                << " seg: " << op.seg_id
                << " dst: " << boost::numeric_cast<double>(op.enriched.distance)
                << " op: " << operation_char(turn_points[it->index].operations[0].operation)
                << operation_char(turn_points[it->index].operations[1].operation)
                << " dsc: " << (turn_points[it->index].discarded ? "T" : "F")
                << " ->vtx " << op.enriched.travels_to_vertex_index
                << " ->ip " << op.enriched.travels_to_ip_index
                << " ->nxt ip " << op.enriched.next_ip_index
                //<< " vis: " << visited_char(op.visited)
                << std::endl;
                ;
        }
    }
#endif
    // END DEBUG

}
Beispiel #7
0
/*
 * Parse a method pointed by start, end is the last character to check (if NULL
 * assume that start is a zero terminated string)
 * => assign enum bit to method.
 * Returns pointer to next char if parse succeeded
 * and NULL otherwise.
 */
char* parse_method(char* start, char* end, unsigned int* method)
{
	int len=0;
	int max=0;

	 if (!start || !method) {
		 LM_ERR("invalid parameter value\n");
		 return NULL;
	 }

	 if(end)
		 max = end - start;
	 *method = METHOD_UNDEF;

	 switch (start[0]) {
		 case 'A':
		 case 'a':
			if(end && max<3)
				goto unknown;

			if ((start[1]=='c' || start[1]=='C')
					&& (start[2]=='k' || start[2]=='K'))
			{
				*method = METHOD_ACK;
				len = 3;
				goto done;
			}
			goto unknown;

		case 'B':
		case 'b':
			if(end && max<3)
				goto unknown;

			if ((start[1]=='y' || start[1]=='Y')
					&& (start[2]=='e' || start[2]=='E'))
			{
				*method = METHOD_BYE;
				len = 3;
				goto done;
			}
			goto unknown;

	 	case 'C':
		case 'c':
			if(end && max<6)
				goto unknown;
			if ((start[1]=='a' || start[1]=='A')
					&& (start[2]=='n' || start[2]=='N')
					&& (start[3]=='c' || start[3]=='C')
					&& (start[4]=='e' || start[4]=='E')
					&& (start[5]=='l' || start[5]=='L'))
			{
				*method = METHOD_CANCEL;
				len = 6;
				goto done;
			}
			goto unknown;

	 	case 'I':
		case 'i':
			if(end && max<4)
				goto unknown;
			if(start[1]=='n' && start[1]=='N')
				goto unknown;

			if ((start[2]=='f' || start[2]=='F')
					&& (start[3]=='o' || start[3]=='O'))
			{
				*method = METHOD_INFO;
				len = 4;
				goto done;
			}

			if(end && max<6)
				goto unknown;
			if ((start[2]=='v' || start[2]=='V')
					&& (start[3]=='i' || start[3]=='I')
					&& (start[4]=='t' || start[4]=='T')
					&& (start[5]=='e' || start[5]=='E'))
			{
				*method = METHOD_INVITE;
				len = 6;
				goto done;
			}
			goto unknown;

	 	case 'M':
		case 'm':
			if(end && max<7)
				goto unknown;
			if ((start[1]=='e' || start[1]=='E')
					&& (start[2]=='s' || start[2]=='S')
					&& (start[3]=='s' || start[3]=='S')
					&& (start[4]=='a' || start[4]=='A')
					&& (start[5]=='g' || start[5]=='G')
					&& (start[6]=='e' || start[6]=='E')) {
				*method = METHOD_MESSAGE;
				len = 7;
				goto done;
			}
			goto unknown;

		case 'N':
		case 'n':
			if(end && max<6)
				goto unknown;
			if ((start[1]=='o' || start[1]=='O')
					&& (start[2]=='t' || start[2]=='T')
					&& (start[3]=='i' || start[3]=='I')
					&& (start[4]=='f' || start[4]=='F')
					&& (start[5]=='y' || start[5]=='Y'))
			{
				*method = METHOD_NOTIFY;
				len = 6;
				goto done;
			}
			goto unknown;

		case 'O':
		case 'o':
			if(end && max<7)
				goto unknown;
			if((start[1]=='p' || start[1]=='P')
					&& (start[2]=='t' || start[2]=='T')
					&& (start[3]=='i' || start[3]=='I')
					&& (start[4]=='o' || start[4]=='O')
					&& (start[5]=='n' || start[5]=='N')
					&& (start[6]=='s' || start[6]=='S'))
			{
				*method = METHOD_OPTIONS;
				len = 7;
				goto done;
			}
			goto unknown;

		case 'P':
		case 'p':
			if(end && max<5)
				goto unknown;
			if((start[1]=='r' || start[1]=='R')
					&& (start[2]=='a' || start[2]=='A')
					&& (start[3]=='c' || start[3]=='C')
					&& (start[4]=='k' || start[4]=='K'))
			{
				*method = METHOD_PRACK;
				len = 5;
				goto done;
			}

			if(end && max<7)
				goto unknown;

			if ((start[1]=='u' || start[1]=='U')
					 && (start[2]=='b' || start[2]=='B')
					 && (start[3]=='l' || start[3]=='L')
					 && (start[4]=='i' || start[4]=='I')
					 && (start[5]=='s' || start[5]=='S')
					 && (start[6]=='h' || start[6]=='H'))
			{
				*method = METHOD_PUBLISH;
				len = 7;
				goto done;
			}
			goto unknown;

		case 'R':
		case 'r':
			if(end && max<5)
				goto unknown;
			if(start[1]!='e' && start[1]!='E')
				goto unknown;

 			if((start[2]=='f' || start[2]=='F')
					 && (start[3]=='e' || start[3]=='E')
					 && (start[4]=='R' || start[4]=='R'))
			{
 				*method = METHOD_REFER;
 				len = 5;
 				goto done;
 			}

			if(end && max<8)
				goto unknown;

			if ((start[2]=='g' || start[2]=='G')
					 && (start[3]=='i' || start[3]=='I')
					 && (start[4]=='s' || start[4]=='S')
					 && (start[5]=='t' || start[5]=='T')
					 && (start[6]=='e' || start[6]=='E')
					 && (start[7]=='r' || start[7]=='R'))
			{
				*method = METHOD_REGISTER;
				len = 8;
				goto done;
			}
			goto unknown;

	 	case 'S':
	 	case 's':
			if(end && max<9)
				goto unknown;
	 		if ((start[1]=='u' || start[1]=='U')
					 && (start[2]=='b' || start[2]=='B')
					 && (start[3]=='s' || start[3]=='S')
					 && (start[4]=='c' || start[4]=='C')
					 && (start[5]=='r' || start[5]=='R')
					 && (start[6]=='i' || start[6]=='I')
					 && (start[7]=='b' || start[7]=='B')
					 && (start[8]=='e' || start[8]=='E'))
			{
	 			*method = METHOD_SUBSCRIBE;
	 			len = 9;
				goto done;
			}
			goto unknown;

		case 'U':
		case 'u':
			if(end && max<6)
				goto unknown;
			if ((start[1]=='p' || start[1]=='P')
					&& (start[2]=='d' || start[2]=='D')
					&& (start[3]=='a' || start[3]=='A')
					&& (start[4]=='t' || start[4]=='T')
					&& (start[5]=='e' || start[5]=='E')) {
				*method = METHOD_UPDATE;
				len = 6;
				goto done;
			}
 			goto unknown;

		default:
			goto unknown;
		}

done:
	if(!end || (end && len < max))
	{
		if(start[len]!='\0' && start[len]!=',' && start[len]!=' '
				&& start[len]!='\t' && start[len]!='\r' && start[len]!='\n')
			goto unknown;
	}

	return (start+len);

unknown:
	update_stat(unsupported_methods, 1);
	*method = METHOD_OTHER;
	if(end)
	{
		while(len < max)
		{
			if((start[len]=='\0' || start[len]==',' || start[len]==' '
						|| start[len]=='\t' || start[len]=='\r'
						|| start[len]=='\n'))
				return (start+len);

			if(!method_char(start[len]))
			{
				LM_ERR("invalid character %c\n", start[len]);
				return NULL;
			}

			len++;
		}
		return end;
	}

	while(start[len]!='\0' && start[len]!=',' && start[len]!=' '
			&& start[len]!='\t' && start[len]!='\r' && start[len]!='\n')
	{
		if(!method_char(start[len]))
		{
			LM_ERR("invalid character %c!\n", start[len]);
			return NULL;
		}
		len++;
	}

	return (start+len);
}
inline void enrich_assign(Operations& operations, Turns& turns)
{
    typedef typename boost::range_value<Turns>::type turn_type;
    typedef typename turn_type::turn_operation_type op_type;
    typedef typename boost::range_iterator<Operations>::type iterator_type;


    if (operations.size() > 0)
    {
        // Assign travel-to-vertex/ip index for each turning point.
        // Iterator "next" is circular

        geometry::ever_circling_range_iterator<Operations const> next(operations);
        ++next;

        for (iterator_type it = boost::begin(operations);
             it != boost::end(operations); ++it)
        {
            turn_type& turn = turns[it->turn_index];
            op_type& op = turn.operations[it->operation_index];

            // Normal behaviour: next should point at next turn:
            if (it->turn_index == next->turn_index)
            {
                ++next;
            }

            // Cluster behaviour: next should point after cluster, unless
            // their seg_ids are not the same
            while (turn.cluster_id != -1
                   && it->turn_index != next->turn_index
                   && turn.cluster_id == turns[next->turn_index].cluster_id
                   && op.seg_id == turns[next->turn_index].operations[next->operation_index].seg_id)
            {
                ++next;
            }

            turn_type const& next_turn = turns[next->turn_index];
            op_type const& next_op = next_turn.operations[next->operation_index];

            op.enriched.travels_to_ip_index
                    = static_cast<signed_size_type>(next->turn_index);
            op.enriched.travels_to_vertex_index
                    = next->subject->seg_id.segment_index;

            if (op.seg_id.segment_index == next_op.seg_id.segment_index
                    && op.fraction < next_op.fraction)
            {
                // Next turn is located further on same segment
                // assign next_ip_index
                // (this is one not circular therefore fraction is considered)
                op.enriched.next_ip_index = static_cast<signed_size_type>(next->turn_index);
            }
        }
    }

    // DEBUG
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
    {
        for (iterator_type it = boost::begin(operations);
             it != boost::end(operations);
             ++it)
        {
            op_type& op = turns[it->turn_index]
                .operations[it->operation_index];

            std::cout << it->turn_index
                << " cl=" << turns[it->turn_index].cluster_id
                << " meth=" << method_char(turns[it->turn_index].method)
                << " seg=" << op.seg_id
                << " dst=" << op.fraction // needs define
                << " op=" << operation_char(turns[it->turn_index].operations[0].operation)
                << operation_char(turns[it->turn_index].operations[1].operation)
                << " (" << operation_char(op.operation) << ")"
                << " nxt=" << op.enriched.next_ip_index
                << " / " << op.enriched.travels_to_ip_index
                << " [vx " << op.enriched.travels_to_vertex_index << "]"
                << std::endl;
                ;
        }
    }
#endif
    // END DEBUG

}